adlint 1.10.0 → 1.12.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +197 -4
- data/MANIFEST +17 -0
- data/NEWS +23 -4
- data/etc/mesg.d/en_US/messages.yml +14 -1
- data/etc/mesg.d/ja_JP/messages.yml +14 -1
- data/features/message_detection/W0093.feature +87 -0
- data/features/message_detection/W0687.feature +25 -0
- data/features/message_detection/W0688.feature +63 -0
- data/features/message_detection/W0689.feature +46 -0
- data/features/message_detection/W0690.feature +35 -0
- data/features/message_detection/W0698.feature +3 -2
- data/features/message_detection/W0703.feature +1 -0
- data/features/message_detection/W0723.feature +34 -0
- data/features/message_detection/W0732.feature +158 -0
- data/features/message_detection/W0733.feature +158 -0
- data/features/message_detection/W0734.feature +322 -0
- data/features/message_detection/W0735.feature +322 -0
- data/features/message_detection/W1052.feature +66 -0
- data/features/message_detection/W9001.feature +33 -0
- data/features/message_detection/W9003.feature +131 -0
- data/lib/adlint/c/ctrlexpr.rb +51 -50
- data/lib/adlint/c/domain.rb +237 -223
- data/lib/adlint/c/expr.rb +6 -8
- data/lib/adlint/c/interp.rb +8 -11
- data/lib/adlint/c/message.rb +20 -0
- data/lib/adlint/c/message_shima.rb +63 -0
- data/lib/adlint/c/object.rb +5 -4
- data/lib/adlint/c/operator.rb +99 -0
- data/lib/adlint/c/parser.rb +2 -2
- data/lib/adlint/c/parser.y +2 -2
- data/lib/adlint/c/phase.rb +6 -1
- data/lib/adlint/c/syntax.rb +442 -30
- data/lib/adlint/c/type.rb +449 -363
- data/lib/adlint/c/value.rb +96 -25
- data/lib/adlint/c.rb +1 -0
- data/lib/adlint/prelude.rb +16 -18
- data/lib/adlint/version.rb +2 -2
- data/share/doc/developers_guide_ja.html +11 -5
- data/share/doc/developers_guide_ja.texi +9 -3
- data/share/doc/users_guide_en.html +697 -131
- data/share/doc/users_guide_en.texi +491 -41
- data/share/doc/users_guide_ja.html +709 -139
- data/share/doc/users_guide_ja.texi +499 -45
- data/spec/adlint/c/ctrlexpr_spec.rb +168 -0
- data/spec/adlint/c/domain_spec.rb +835 -0
- data/spec/adlint/c/operator_spec.rb +406 -0
- data/spec/adlint/c/syntax_spec.rb +717 -0
- data/spec/adlint/c/type_spec.rb +55 -30
- metadata +19 -2
data/lib/adlint/c/interp.rb
CHANGED
@@ -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)
|
65
|
-
def visit_ansi_function_definition(node)
|
66
|
-
def visit_kandr_function_definition(node)
|
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!(
|
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!(
|
1223
|
+
variable.narrow_value_domain!(Operator::GE, orig_value)
|
1227
1224
|
when :decrease
|
1228
|
-
variable.narrow_value_domain!(
|
1225
|
+
variable.narrow_value_domain!(Operator::LE, orig_value)
|
1229
1226
|
end
|
1230
1227
|
end
|
1231
1228
|
end
|
data/lib/adlint/c/message.rb
CHANGED
@@ -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
|
data/lib/adlint/c/object.rb
CHANGED
@@ -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!(
|
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!(
|
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!(
|
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!(
|
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
|
data/lib/adlint/c/parser.rb
CHANGED
@@ -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[
|
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[
|
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
|
|
data/lib/adlint/c/parser.y
CHANGED
@@ -195,7 +195,7 @@ postfix_expression
|
|
195
195
|
{
|
196
196
|
checkpoint(val[0].location)
|
197
197
|
|
198
|
-
result = PostfixIncrementExpression.new(val[
|
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[
|
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
|
}
|
data/lib/adlint/c/phase.rb
CHANGED
@@ -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
|