adlint 1.10.0 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|