adlint 1.10.0 → 1.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/ChangeLog +197 -4
  2. data/MANIFEST +17 -0
  3. data/NEWS +23 -4
  4. data/etc/mesg.d/en_US/messages.yml +14 -1
  5. data/etc/mesg.d/ja_JP/messages.yml +14 -1
  6. data/features/message_detection/W0093.feature +87 -0
  7. data/features/message_detection/W0687.feature +25 -0
  8. data/features/message_detection/W0688.feature +63 -0
  9. data/features/message_detection/W0689.feature +46 -0
  10. data/features/message_detection/W0690.feature +35 -0
  11. data/features/message_detection/W0698.feature +3 -2
  12. data/features/message_detection/W0703.feature +1 -0
  13. data/features/message_detection/W0723.feature +34 -0
  14. data/features/message_detection/W0732.feature +158 -0
  15. data/features/message_detection/W0733.feature +158 -0
  16. data/features/message_detection/W0734.feature +322 -0
  17. data/features/message_detection/W0735.feature +322 -0
  18. data/features/message_detection/W1052.feature +66 -0
  19. data/features/message_detection/W9001.feature +33 -0
  20. data/features/message_detection/W9003.feature +131 -0
  21. data/lib/adlint/c/ctrlexpr.rb +51 -50
  22. data/lib/adlint/c/domain.rb +237 -223
  23. data/lib/adlint/c/expr.rb +6 -8
  24. data/lib/adlint/c/interp.rb +8 -11
  25. data/lib/adlint/c/message.rb +20 -0
  26. data/lib/adlint/c/message_shima.rb +63 -0
  27. data/lib/adlint/c/object.rb +5 -4
  28. data/lib/adlint/c/operator.rb +99 -0
  29. data/lib/adlint/c/parser.rb +2 -2
  30. data/lib/adlint/c/parser.y +2 -2
  31. data/lib/adlint/c/phase.rb +6 -1
  32. data/lib/adlint/c/syntax.rb +442 -30
  33. data/lib/adlint/c/type.rb +449 -363
  34. data/lib/adlint/c/value.rb +96 -25
  35. data/lib/adlint/c.rb +1 -0
  36. data/lib/adlint/prelude.rb +16 -18
  37. data/lib/adlint/version.rb +2 -2
  38. data/share/doc/developers_guide_ja.html +11 -5
  39. data/share/doc/developers_guide_ja.texi +9 -3
  40. data/share/doc/users_guide_en.html +697 -131
  41. data/share/doc/users_guide_en.texi +491 -41
  42. data/share/doc/users_guide_ja.html +709 -139
  43. data/share/doc/users_guide_ja.texi +499 -45
  44. data/spec/adlint/c/ctrlexpr_spec.rb +168 -0
  45. data/spec/adlint/c/domain_spec.rb +835 -0
  46. data/spec/adlint/c/operator_spec.rb +406 -0
  47. data/spec/adlint/c/syntax_spec.rb +717 -0
  48. data/spec/adlint/c/type_spec.rb +55 -30
  49. metadata +19 -2
@@ -37,6 +37,7 @@ require "adlint/c/syntax"
37
37
  require "adlint/c/expr"
38
38
  require "adlint/c/conv"
39
39
  require "adlint/c/option"
40
+ require "adlint/c/operator"
40
41
  require "adlint/c/util"
41
42
 
42
43
  module AdLint #:nodoc:
@@ -55,18 +56,13 @@ module C #:nodoc:
55
56
  end
56
57
 
57
58
  class ExecutionDriver < SyntaxTreeVisitor
58
- include InterpreterMediator
59
-
60
59
  def initialize(interpreter)
61
60
  @interpreter = interpreter
62
61
  end
63
62
 
64
- def visit_declaration(node) interpret(node) end
65
- def visit_ansi_function_definition(node) interpret(node) end
66
- def visit_kandr_function_definition(node) interpret(node) end
67
-
68
- private
69
- def interpreter; @interpreter end
63
+ def visit_declaration(node) @interpreter.execute(node) end
64
+ def visit_ansi_function_definition(node) @interpreter.execute(node) end
65
+ def visit_kandr_function_definition(node) @interpreter.execute(node) end
70
66
  end
71
67
  private_constant :ExecutionDriver
72
68
  end
@@ -1216,16 +1212,17 @@ module C #:nodoc:
1216
1212
  iteration_statement.varying_variable_names.each do |name|
1217
1213
  if variable = variable_named(name)
1218
1214
  varying_vars[variable] = variable.value.dup
1219
- variable.widen_value_domain!(:==, variable.type.arbitrary_value)
1215
+ variable.widen_value_domain!(Operator::EQ,
1216
+ variable.type.arbitrary_value)
1220
1217
  end
1221
1218
  end
1222
1219
 
1223
1220
  varying_vars.each do |variable, orig_value|
1224
1221
  case deduct_variable_varying_path(variable, iteration_statement)
1225
1222
  when :increase
1226
- variable.narrow_value_domain!(:>=, orig_value)
1223
+ variable.narrow_value_domain!(Operator::GE, orig_value)
1227
1224
  when :decrease
1228
- variable.narrow_value_domain!(:<=, orig_value)
1225
+ variable.narrow_value_domain!(Operator::LE, orig_value)
1229
1226
  end
1230
1227
  end
1231
1228
  end
@@ -15024,5 +15024,25 @@ module C #:nodoc:
15024
15024
  end
15025
15025
  end
15026
15026
 
15027
+ class W9003 < PassiveMessageDetection
15028
+ def initialize(context)
15029
+ super
15030
+ interp = context[:c_interpreter]
15031
+ interp.on_implicit_conv_performed += method(:check)
15032
+ end
15033
+
15034
+ private
15035
+ def check(initializer_or_expression, original_variable, result_variable)
15036
+ from_type = original_variable.type
15037
+ to_type = result_variable.type
15038
+
15039
+ unless from_type.standard? && to_type.standard?
15040
+ unless from_type.convertible?(to_type)
15041
+ W(:W9003, initializer_or_expression.location, from_type.brief_image)
15042
+ end
15043
+ end
15044
+ end
15045
+ end
15046
+
15027
15047
  end
15028
15048
  end
@@ -308,6 +308,69 @@ module C #:nodoc:
308
308
  end
309
309
  end
310
310
 
311
+ class W0732 < PassiveMessageDetection
312
+ def initialize(context)
313
+ super
314
+ visitor = context[:c_visitor]
315
+ visitor.enter_logical_and_expression += method(:check)
316
+ end
317
+
318
+ private
319
+ def check(expr)
320
+ if expr.lhs_operand.arithmetic? || expr.lhs_operand.bitwise?
321
+ if expr.rhs_operand.arithmetic? || expr.rhs_operand.bitwise?
322
+ W(:W0732, expr.location)
323
+ end
324
+ end
325
+ end
326
+ end
327
+
328
+ class W0733 < PassiveMessageDetection
329
+ def initialize(context)
330
+ super
331
+ visitor = context[:c_visitor]
332
+ visitor.enter_logical_or_expression += method(:check)
333
+ end
334
+
335
+ private
336
+ def check(expr)
337
+ if expr.lhs_operand.arithmetic? || expr.lhs_operand.bitwise?
338
+ if expr.rhs_operand.arithmetic? || expr.rhs_operand.bitwise?
339
+ W(:W0733, expr.location)
340
+ end
341
+ end
342
+ end
343
+ end
344
+
345
+ class W0734 < PassiveMessageDetection
346
+ def initialize(context)
347
+ super
348
+ visitor = context[:c_visitor]
349
+ visitor.enter_logical_and_expression += method(:check)
350
+ visitor.enter_logical_or_expression += method(:check)
351
+ end
352
+
353
+ private
354
+ def check(expr)
355
+ if expr.lhs_operand.arithmetic? || expr.lhs_operand.bitwise?
356
+ unless expr.rhs_operand.arithmetic? || expr.rhs_operand.bitwise?
357
+ W(:W0734, expr.lhs_operand.location)
358
+ end
359
+ end
360
+ end
361
+ end
362
+
363
+ class W0735 < W0734
364
+ private
365
+ def check(expr)
366
+ if expr.rhs_operand.arithmetic? || expr.rhs_operand.bitwise?
367
+ unless expr.lhs_operand.arithmetic? || expr.lhs_operand.bitwise?
368
+ W(:W0735, expr.rhs_operand.location)
369
+ end
370
+ end
371
+ end
372
+ end
373
+
311
374
  class W0781 < PassiveMessageDetection
312
375
  def initialize(context)
313
376
  super
@@ -34,6 +34,7 @@ require "adlint/c/syntax"
34
34
  require "adlint/c/value"
35
35
  require "adlint/c/scope"
36
36
  require "adlint/c/seqp"
37
+ require "adlint/c/operator"
37
38
 
38
39
  module AdLint #:nodoc:
39
40
  module C #:nodoc:
@@ -209,23 +210,23 @@ module C #:nodoc:
209
210
  assign!(self.type.undefined_value)
210
211
  end
211
212
 
212
- def narrow_value_domain!(operator_symbol, value)
213
+ def narrow_value_domain!(operator, value)
213
214
  unless self_value = modifiable_value
214
215
  assign!(type.arbitrary_value)
215
216
  self_value = modifiable_value
216
217
  end
217
218
 
218
- self_value.narrow_domain!(operator_symbol, value.coerce_to(type))
219
+ self_value.narrow_domain!(operator, value.coerce_to(type))
219
220
  self_value.exist?
220
221
  end
221
222
 
222
- def widen_value_domain!(operator_symbol, value)
223
+ def widen_value_domain!(operator, value)
223
224
  unless self_value = modifiable_value
224
225
  assign!(type.nil_value)
225
226
  self_value = modifiable_value
226
227
  end
227
228
 
228
- self_value.widen_domain!(operator_symbol, value.coerce_to(type))
229
+ self_value.widen_domain!(operator, value.coerce_to(type))
229
230
  self_value.exist?
230
231
  end
231
232
 
@@ -0,0 +1,99 @@
1
+ # Comparison operator of controlling expressions.
2
+ #
3
+ # Author:: Yutaka Yanoh <mailto:yanoh@users.sourceforge.net>
4
+ # Copyright:: Copyright (C) 2010-2012, OGIS-RI Co.,Ltd.
5
+ # License:: GPLv3+: GNU General Public License version 3 or later
6
+ #
7
+ # Owner:: Yutaka Yanoh <mailto:yanoh@users.sourceforge.net>
8
+
9
+ #--
10
+ # ___ ____ __ ___ _________
11
+ # / | / _ |/ / / / | / /__ __/ Source Code Static Analyzer
12
+ # / /| | / / / / / / / |/ / / / AdLint - Advanced Lint
13
+ # / __ |/ /_/ / /___/ / /| / / /
14
+ # /_/ |_|_____/_____/_/_/ |_/ /_/ Copyright (C) 2010-2012, OGIS-RI Co.,Ltd.
15
+ #
16
+ # This file is part of AdLint.
17
+ #
18
+ # AdLint is free software: you can redistribute it and/or modify it under the
19
+ # terms of the GNU General Public License as published by the Free Software
20
+ # Foundation, either version 3 of the License, or (at your option) any later
21
+ # version.
22
+ #
23
+ # AdLint is distributed in the hope that it will be useful, but WITHOUT ANY
24
+ # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
25
+ # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
26
+ #
27
+ # You should have received a copy of the GNU General Public License along with
28
+ # AdLint. If not, see <http://www.gnu.org/licenses/>.
29
+ #
30
+ #++
31
+
32
+ module AdLint #:nodoc:
33
+ module C #:nodoc:
34
+
35
+ class Operator
36
+ def initialize(token_or_symbol)
37
+ case token_or_symbol
38
+ when Token
39
+ @sym = token_or_symbol.type.to_sym
40
+ when ::Symbol
41
+ @sym = token_or_symbol
42
+ end
43
+ end
44
+
45
+ def to_sym
46
+ @sym
47
+ end
48
+
49
+ def eql?(rhs)
50
+ case rhs
51
+ when Operator
52
+ @sym == rhs.to_sym
53
+ else
54
+ super
55
+ end
56
+ end
57
+
58
+ alias :== :eql?
59
+
60
+ def hash
61
+ @sym.hash
62
+ end
63
+ end
64
+
65
+ class ComparisonOperator < Operator
66
+ def for_complement
67
+ case self
68
+ when Operator::EQ then Operator::NE
69
+ when Operator::NE then Operator::EQ
70
+ when Operator::LT then Operator::GE
71
+ when Operator::GT then Operator::LE
72
+ when Operator::LE then Operator::GT
73
+ when Operator::GE then Operator::LT
74
+ else self
75
+ end
76
+ end
77
+
78
+ def for_commutation
79
+ case self
80
+ when Operator::LT then Operator::GT
81
+ when Operator::GT then Operator::LT
82
+ when Operator::LE then Operator::GE
83
+ when Operator::GE then Operator::LE
84
+ else self
85
+ end
86
+ end
87
+ end
88
+
89
+ class Operator
90
+ EQ = ComparisonOperator.new(:==)
91
+ NE = ComparisonOperator.new(:!=)
92
+ LT = ComparisonOperator.new(:<)
93
+ GT = ComparisonOperator.new(:>)
94
+ LE = ComparisonOperator.new(:<=)
95
+ GE = ComparisonOperator.new(:>=)
96
+ end
97
+
98
+ end
99
+ end
@@ -1387,7 +1387,7 @@ module_eval(<<'.,.,', 'parser.y', 195)
1387
1387
  def _reduce_15(val, _values, result)
1388
1388
  checkpoint(val[0].location)
1389
1389
 
1390
- result = PostfixIncrementExpression.new(val[0], val[1])
1390
+ result = PostfixIncrementExpression.new(val[1], val[0])
1391
1391
  result.head_token = val[0].head_token
1392
1392
  result.tail_token = val[1]
1393
1393
 
@@ -1399,7 +1399,7 @@ module_eval(<<'.,.,', 'parser.y', 203)
1399
1399
  def _reduce_16(val, _values, result)
1400
1400
  checkpoint(val[0].location)
1401
1401
 
1402
- result = PostfixDecrementExpression.new(val[0], val[1])
1402
+ result = PostfixDecrementExpression.new(val[1], val[0])
1403
1403
  result.head_token = val[0].head_token
1404
1404
  result.tail_token = val[1]
1405
1405
 
@@ -195,7 +195,7 @@ postfix_expression
195
195
  {
196
196
  checkpoint(val[0].location)
197
197
 
198
- result = PostfixIncrementExpression.new(val[0], val[1])
198
+ result = PostfixIncrementExpression.new(val[1], val[0])
199
199
  result.head_token = val[0].head_token
200
200
  result.tail_token = val[1]
201
201
  }
@@ -203,7 +203,7 @@ postfix_expression
203
203
  {
204
204
  checkpoint(val[0].location)
205
205
 
206
- result = PostfixDecrementExpression.new(val[0], val[1])
206
+ result = PostfixDecrementExpression.new(val[1], val[0])
207
207
  result.head_token = val[0].head_token
208
208
  result.tail_token = val[1]
209
209
  }
@@ -654,6 +654,10 @@ module C #:nodoc:
654
654
  W0729.new(context),
655
655
  W0730.new(context),
656
656
  W0731.new(context),
657
+ W0732.new(context),
658
+ W0733.new(context),
659
+ W0734.new(context),
660
+ W0735.new(context),
657
661
  W0736.new(context),
658
662
  W0737.new(context),
659
663
  W0738.new(context),
@@ -741,7 +745,8 @@ module C #:nodoc:
741
745
  W1063.new(context),
742
746
  W1064.new(context),
743
747
  W1065.new(context),
744
- W9001.new(context)
748
+ W9001.new(context),
749
+ W9003.new(context)
745
750
  ]
746
751
  end
747
752
  end