adlint 2.6.2 → 2.6.10

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.
@@ -0,0 +1,138 @@
1
+ Feature: W0611
2
+
3
+ W0611 detects that a controlling expression of the iteration-statement always
4
+ be true.
5
+
6
+ Scenario: controlling variable of for-statement is not updated
7
+ Given a target source named "fixture.c" with:
8
+ """
9
+ static int foo(void)
10
+ {
11
+ int i = 0, j = 0;
12
+ for (; i < 10; ) { /* W0611 */
13
+ j++;
14
+ }
15
+ return j;
16
+ }
17
+ """
18
+ When I successfully run `adlint fixture.c` on noarch
19
+ Then the output should exactly match with:
20
+ | mesg | line | column |
21
+ | W1076 | 1 | 12 |
22
+ | W0534 | 4 | 10 |
23
+ | W0609 | 4 | 14 |
24
+ | W0708 | 5 | 10 |
25
+ | W0611 | 4 | 14 |
26
+ | W0100 | 3 | 9 |
27
+ | W0629 | 1 | 12 |
28
+ | W0425 | 3 | 16 |
29
+ | W0628 | 1 | 12 |
30
+
31
+ Scenario: controlling variable of for-statement is updated
32
+ Given a target source named "fixture.c" with:
33
+ """
34
+ static int foo(void)
35
+ {
36
+ int i = 0, j = 0;
37
+ for (; i < 10; i++) { /* OK */
38
+ j++;
39
+ }
40
+ return j;
41
+ }
42
+ """
43
+ When I successfully run `adlint fixture.c` on noarch
44
+ Then the output should exactly match with:
45
+ | mesg | line | column |
46
+ | W1076 | 1 | 12 |
47
+ | W0534 | 4 | 10 |
48
+ | W0629 | 1 | 12 |
49
+ | W0425 | 3 | 16 |
50
+ | W0628 | 1 | 12 |
51
+
52
+ Scenario: controlling variable of while-statement is not updated
53
+ Given a target source named "fixture.c" with:
54
+ """
55
+ static int foo(void)
56
+ {
57
+ int i = 0, j = 0;
58
+ while (i < 10) { /* W0611 */
59
+ j++;
60
+ }
61
+ return j;
62
+ }
63
+ """
64
+ When I successfully run `adlint fixture.c` on noarch
65
+ Then the output should exactly match with:
66
+ | mesg | line | column |
67
+ | W1076 | 1 | 12 |
68
+ | W0609 | 4 | 14 |
69
+ | W0611 | 4 | 14 |
70
+ | W0100 | 3 | 9 |
71
+ | W0629 | 1 | 12 |
72
+ | W0425 | 3 | 16 |
73
+ | W0628 | 1 | 12 |
74
+
75
+ Scenario: controlling variable of while-statement is updated
76
+ Given a target source named "fixture.c" with:
77
+ """
78
+ static int foo(void)
79
+ {
80
+ int i = 0, j = 0;
81
+ while (i < 10) { /* OK */
82
+ i++;
83
+ j++;
84
+ }
85
+ return j;
86
+ }
87
+ """
88
+ When I successfully run `adlint fixture.c` on noarch
89
+ Then the output should exactly match with:
90
+ | mesg | line | column |
91
+ | W1076 | 1 | 12 |
92
+ | W0629 | 1 | 12 |
93
+ | W0425 | 3 | 16 |
94
+ | W0628 | 1 | 12 |
95
+
96
+ Scenario: controlling variable of do-statement is not updated
97
+ Given a target source named "fixture.c" with:
98
+ """
99
+ static int foo(void)
100
+ {
101
+ int i = 0, j = 0;
102
+ do {
103
+ j++;
104
+ } while (i < 10); /* W0611 */
105
+ return j;
106
+ }
107
+ """
108
+ When I successfully run `adlint fixture.c` on noarch
109
+ Then the output should exactly match with:
110
+ | mesg | line | column |
111
+ | W1076 | 1 | 12 |
112
+ | W0609 | 6 | 16 |
113
+ | W0611 | 6 | 16 |
114
+ | W0100 | 3 | 9 |
115
+ | W0629 | 1 | 12 |
116
+ | W0425 | 3 | 16 |
117
+ | W0628 | 1 | 12 |
118
+
119
+ Scenario: controlling variable of do-statement is updated
120
+ Given a target source named "fixture.c" with:
121
+ """
122
+ static int foo(void)
123
+ {
124
+ int i = 0, j = 0;
125
+ do {
126
+ i++;
127
+ j++;
128
+ } while (i < 10); /* OK */
129
+ return j;
130
+ }
131
+ """
132
+ When I successfully run `adlint fixture.c` on noarch
133
+ Then the output should exactly match with:
134
+ | mesg | line | column |
135
+ | W1076 | 1 | 12 |
136
+ | W0629 | 1 | 12 |
137
+ | W0425 | 3 | 16 |
138
+ | W0628 | 1 | 12 |
@@ -0,0 +1,66 @@
1
+ Feature: W0708
2
+
3
+ W0708 detects that a controlling variable of for-statement is updated in the
4
+ loop body.
5
+
6
+ Scenario: address of the controlling variable is passed to a function in the
7
+ controlling part of for-statement
8
+ Given a target source named "fixture.c" with:
9
+ """
10
+ static int bar(int *);
11
+
12
+ static void foo(void)
13
+ {
14
+ int i;
15
+ for (i = 0; (bar(&i)) && (i < 10); ) { /* OK */
16
+ }
17
+ }
18
+ """
19
+ When I successfully run `adlint fixture.c` on noarch
20
+ Then the output should exactly match with:
21
+ | mesg | line | column |
22
+ | W1076 | 3 | 13 |
23
+ | W0629 | 3 | 13 |
24
+ | W0628 | 3 | 13 |
25
+
26
+ Scenario: address of the controlling variable is passed to a function in the
27
+ controlling part of for-statement
28
+ Given a target source named "fixture.c" with:
29
+ """
30
+ static int bar(int *);
31
+
32
+ static void foo(void)
33
+ {
34
+ int i;
35
+ for (i = 0; (bar(&i)) && (i < 10); i++) { /* OK */
36
+ }
37
+ }
38
+ """
39
+ When I successfully run `adlint fixture.c` on noarch
40
+ Then the output should exactly match with:
41
+ | mesg | line | column |
42
+ | W1076 | 3 | 13 |
43
+ | W0629 | 3 | 13 |
44
+ | W0628 | 3 | 13 |
45
+
46
+ Scenario: address of the controlling variable is passed to a function in the
47
+ controlling part of for-statement
48
+ Given a target source named "fixture.c" with:
49
+ """
50
+ static int bar(int *);
51
+
52
+ static void foo(void)
53
+ {
54
+ int i;
55
+ for (i = 0; (bar(&i)) && (i < 10); i++) {
56
+ if (i == 5) { i++; } /* W0708 */
57
+ }
58
+ }
59
+ """
60
+ When I successfully run `adlint fixture.c` on noarch
61
+ Then the output should exactly match with:
62
+ | mesg | line | column |
63
+ | W1076 | 3 | 13 |
64
+ | W0708 | 7 | 24 |
65
+ | W0629 | 3 | 13 |
66
+ | W0628 | 3 | 13 |
@@ -126,3 +126,30 @@ Feature: W1069
126
126
  | W1071 | 1 | 12 |
127
127
  | W0629 | 1 | 12 |
128
128
  | W0628 | 1 | 12 |
129
+
130
+ Scenario: incomplete `if-else-if' statement chain in a complete `if-else'
131
+ statement
132
+ Given a target source named "fixture.c" with:
133
+ """
134
+ static void foo(int i)
135
+ {
136
+ if (i == 0) {
137
+ return;
138
+ }
139
+ else {
140
+ if (i == 1) { /* W1069 */
141
+ }
142
+ else if (i == 2) {
143
+ }
144
+ }
145
+ }
146
+ """
147
+ When I successfully run `adlint fixture.c` on noarch
148
+ Then the output should exactly match with:
149
+ | mesg | line | column |
150
+ | W1076 | 1 | 13 |
151
+ | W0104 | 1 | 21 |
152
+ | W1071 | 1 | 13 |
153
+ | W0629 | 1 | 13 |
154
+ | W1069 | 7 | 9 |
155
+ | W0628 | 1 | 13 |
@@ -141,3 +141,145 @@ Feature: W1073
141
141
  | W0010 | 5 | 23 |
142
142
  | W0086 | 5 | 23 |
143
143
  | W0628 | 3 | 12 |
144
+
145
+ Scenario: standalone function-call-expression as the controlling expression
146
+ of if-statement
147
+ Given a target source named "fixture.c" with:
148
+ """
149
+ static int bar(int *);
150
+
151
+ static int foo(void)
152
+ {
153
+ int i = 0;
154
+ if (bar(&i)) { /* OK */
155
+ return i;
156
+ }
157
+ return 0;
158
+ }
159
+ """
160
+ When I successfully run `adlint fixture.c` on noarch
161
+ Then the output should exactly match with:
162
+ | mesg | line | column |
163
+ | W1076 | 3 | 12 |
164
+ | W1071 | 3 | 12 |
165
+ | W0629 | 3 | 12 |
166
+ | W0114 | 6 | 5 |
167
+ | W0628 | 3 | 12 |
168
+
169
+ Scenario: standalone function-call-expression as the controlling expression
170
+ of if-else-statement
171
+ Given a target source named "fixture.c" with:
172
+ """
173
+ static int bar(int *);
174
+
175
+ static int foo(void)
176
+ {
177
+ int i = 0;
178
+ if (bar(&i)) { /* OK */
179
+ return i;
180
+ } else {
181
+ return 0;
182
+ }
183
+ }
184
+ """
185
+ When I successfully run `adlint fixture.c` on noarch
186
+ Then the output should exactly match with:
187
+ | mesg | line | column |
188
+ | W1076 | 3 | 12 |
189
+ | W1071 | 3 | 12 |
190
+ | W0629 | 3 | 12 |
191
+ | W0114 | 6 | 5 |
192
+ | W0628 | 3 | 12 |
193
+
194
+ Scenario: standalone function-call-expression as the controlling expression
195
+ of while-statement
196
+ Given a target source named "fixture.c" with:
197
+ """
198
+ static int bar(int *);
199
+
200
+ static int foo(void)
201
+ {
202
+ int i = 0;
203
+ while (bar(&i)) { /* OK */
204
+ i++;
205
+ }
206
+ return i;
207
+ }
208
+ """
209
+ When I successfully run `adlint fixture.c` on noarch
210
+ Then the output should exactly match with:
211
+ | mesg | line | column |
212
+ | W1076 | 3 | 12 |
213
+ | W0629 | 3 | 12 |
214
+ | W0114 | 6 | 5 |
215
+ | W0628 | 3 | 12 |
216
+
217
+ Scenario: standalone function-call-expression as the controlling expression
218
+ of do-statement
219
+ Given a target source named "fixture.c" with:
220
+ """
221
+ static int bar(int *);
222
+
223
+ static int foo(void)
224
+ {
225
+ int i = 0;
226
+ do {
227
+ i++;
228
+ } while (bar(&i)); /* OK */
229
+ return i;
230
+ }
231
+ """
232
+ When I successfully run `adlint fixture.c` on noarch
233
+ Then the output should exactly match with:
234
+ | mesg | line | column |
235
+ | W1076 | 3 | 12 |
236
+ | W0629 | 3 | 12 |
237
+ | W0114 | 6 | 5 |
238
+ | W0628 | 3 | 12 |
239
+
240
+ Scenario: standalone function-call-expression as the controlling expression
241
+ of for-statement
242
+ Given a target source named "fixture.c" with:
243
+ """
244
+ static int bar(int *);
245
+
246
+ static int foo(void)
247
+ {
248
+ int i, j = 0;
249
+ for (i = 0; bar(&i); i++) { /* OK */
250
+ j++;
251
+ }
252
+ return j;
253
+ }
254
+ """
255
+ When I successfully run `adlint fixture.c` on noarch
256
+ Then the output should exactly match with:
257
+ | mesg | line | column |
258
+ | W1076 | 3 | 12 |
259
+ | W0629 | 3 | 12 |
260
+ | W0114 | 6 | 5 |
261
+ | W0425 | 5 | 12 |
262
+ | W0628 | 3 | 12 |
263
+
264
+ Scenario: standalone function-call-expression as the controlling expression
265
+ of c99-for-statement
266
+ Given a target source named "fixture.c" with:
267
+ """
268
+ static int bar(int *);
269
+
270
+ static int foo(void)
271
+ {
272
+ int j = 0;
273
+ for (int i = 0; bar(&i); i++) { /* OK */
274
+ j++;
275
+ }
276
+ return j;
277
+ }
278
+ """
279
+ When I successfully run `adlint fixture.c` on noarch
280
+ Then the output should exactly match with:
281
+ | mesg | line | column |
282
+ | W1076 | 3 | 12 |
283
+ | W0629 | 3 | 12 |
284
+ | W0114 | 6 | 5 |
285
+ | W0628 | 3 | 12 |
@@ -71,15 +71,10 @@ module C #:nodoc:
71
71
 
72
72
  if target_expr
73
73
  new_manip = ValueDomainNarrower.new(@interpreter, target_expr)
74
- begin
75
- if @branch.implicit_condition?
76
- @interpreter._quiet = true
77
- end
74
+ if @branch.implicit_condition?
75
+ eval_quietly { new_manip.prepare! }
76
+ else
78
77
  new_manip.prepare!
79
- ensure
80
- if @branch.implicit_condition?
81
- @interpreter._quiet = false
82
- end
83
78
  end
84
79
  else
85
80
  new_manip = NilValueDomainNarrower.new(@interpreter, @branch.group)
@@ -94,15 +89,10 @@ module C #:nodoc:
94
89
 
95
90
  if target_expr
96
91
  new_manip = ValueDomainWidener.new(@interpreter, target_expr)
97
- begin
98
- if @branch.implicit_condition?
99
- @interpreter._quiet = true
100
- end
92
+ if @branch.implicit_condition?
93
+ eval_quietly { new_manip.prepare! }
94
+ else
101
95
  new_manip.prepare!
102
- ensure
103
- if @branch.implicit_condition?
104
- @interpreter._quiet = false
105
- end
106
96
  end
107
97
  else
108
98
  new_manip = NilValueDomainWidener.new(@interpreter, @branch.group)
@@ -133,6 +123,19 @@ module C #:nodoc:
133
123
  # complex to thin value domains of controlling variables.
134
124
  @target_expr && !collect_logical_and_expressions(@target_expr).empty?
135
125
  end
126
+
127
+ private
128
+ def eval_quietly(&block)
129
+ originally_quiet = @interpreter.quiet?
130
+ if @branch.implicit_condition? && !originally_quiet
131
+ @interpreter._quiet = true
132
+ end
133
+ yield
134
+ ensure
135
+ if @branch.implicit_condition? && !originally_quiet
136
+ @interpreter._quiet = false
137
+ end
138
+ end
136
139
  end
137
140
 
138
141
  class ValueDomainManipulator < SyntaxTreeVisitor
@@ -596,6 +599,9 @@ module C #:nodoc:
596
599
  @narrowed_values = manip.narrowed_values.merge(@narrowed_values)
597
600
  end
598
601
  ensure
602
+ if result && result.variable?
603
+ notify_variable_value_referred(node, result)
604
+ end
599
605
  if seqp = node.subsequent_sequence_point
600
606
  notify_sequence_point_reached(seqp)
601
607
  end
@@ -981,7 +981,10 @@ module C #:nodoc:
981
981
  ctrlexpr_val = ScalarValue.of_arbitrary
982
982
  ctrlexpr = nil
983
983
  else
984
- ctrlexpr_val = value_of(interpret(orig_ctrlexpr))
984
+ ctrlexpr_var = object_to_variable(interpret(orig_ctrlexpr))
985
+ ctrlexpr_val = value_of(ctrlexpr_var)
986
+ notify_variable_value_referred(orig_ctrlexpr, ctrlexpr_var)
987
+ notify_sequence_point_reached(SequencePoint.new(orig_ctrlexpr))
985
988
  ctrlexpr = orig_ctrlexpr.to_normalized_logical
986
989
  end
987
990
  notify_if_ctrlexpr_evaled(node, ctrlexpr_val)
@@ -1011,7 +1014,10 @@ module C #:nodoc:
1011
1014
  ctrlexpr_val = ScalarValue.of_arbitrary
1012
1015
  ctrlexpr = nil
1013
1016
  else
1014
- ctrlexpr_val = value_of(interpret(orig_ctrlexpr))
1017
+ ctrlexpr_var = object_to_variable(interpret(orig_ctrlexpr))
1018
+ ctrlexpr_val = value_of(ctrlexpr_var)
1019
+ notify_variable_value_referred(orig_ctrlexpr, ctrlexpr_var)
1020
+ notify_sequence_point_reached(SequencePoint.new(orig_ctrlexpr))
1015
1021
  ctrlexpr = orig_ctrlexpr.to_normalized_logical
1016
1022
  end
1017
1023
  notify_if_else_ctrlexpr_evaled(node, ctrlexpr_val)
@@ -1046,7 +1052,10 @@ module C #:nodoc:
1046
1052
 
1047
1053
  widen_varying_variable_value_domain(node)
1048
1054
 
1049
- ctrlexpr_val = value_of(interpret(node.expression))
1055
+ ctrlexpr_var = object_to_variable(interpret(node.expression))
1056
+ ctrlexpr_val = value_of(ctrlexpr_var)
1057
+ notify_variable_value_referred(node.expression, ctrlexpr_var)
1058
+ notify_sequence_point_reached(SequencePoint.new(node.expression))
1050
1059
  notify_while_ctrlexpr_evaled(node, ctrlexpr_val)
1051
1060
 
1052
1061
  orig_ctrlexpr, ctrlexpr = node.deduct_controlling_expression
@@ -1094,7 +1103,10 @@ module C #:nodoc:
1094
1103
  leave_iteration_statement(orig_ctrlexpr)
1095
1104
  end
1096
1105
 
1097
- ctrlexpr_val = value_of(interpret(node.expression))
1106
+ ctrlexpr_var = object_to_variable(interpret(node.expression))
1107
+ ctrlexpr_val = value_of(ctrlexpr_var)
1108
+ notify_variable_value_referred(node.expression, ctrlexpr_var)
1109
+ notify_sequence_point_reached(SequencePoint.new(node.expression))
1098
1110
  notify_do_ctrlexpr_evaled(node, ctrlexpr_val)
1099
1111
  ensure
1100
1112
  notify_do_stmt_ended(node)
@@ -1113,7 +1125,10 @@ module C #:nodoc:
1113
1125
 
1114
1126
  node.condition_statement.executed = true
1115
1127
  if explicit_ctrlexpr = node.condition_statement.expression
1116
- ctrlexpr_val = value_of(interpret(explicit_ctrlexpr))
1128
+ ctrlexpr_var = object_to_variable(interpret(explicit_ctrlexpr))
1129
+ ctrlexpr_val = value_of(ctrlexpr_var)
1130
+ notify_variable_value_referred(explicit_ctrlexpr, ctrlexpr_var)
1131
+ notify_sequence_point_reached(SequencePoint.new(explicit_ctrlexpr))
1117
1132
  notify_for_ctrlexpr_evaled(node, ctrlexpr_val)
1118
1133
  else
1119
1134
  ctrlexpr_val = ScalarValue.of_true
@@ -1143,7 +1158,10 @@ module C #:nodoc:
1143
1158
 
1144
1159
  node.condition_statement.executed = true
1145
1160
  if explicit_ctrlexpr = node.condition_statement.expression
1146
- ctrlexpr_val = value_of(interpret(explicit_ctrlexpr))
1161
+ ctrlexpr_var = object_to_variable(interpret(explicit_ctrlexpr))
1162
+ ctrlexpr_val = value_of(ctrlexpr_var)
1163
+ notify_variable_value_referred(explicit_ctrlexpr, ctrlexpr_var)
1164
+ notify_sequence_point_reached(SequencePoint.new(explicit_ctrlexpr))
1147
1165
  notify_c99_for_ctrlexpr_evaled(node, ctrlexpr_val)
1148
1166
  else
1149
1167
  ctrlexpr_val = ScalarValue.of_true
@@ -1243,7 +1261,9 @@ module C #:nodoc:
1243
1261
  # causes "logical-expression must be false" warnings about a
1244
1262
  # one-time-for-loop. To avoid this, now, workarounds are in
1245
1263
  # builtin code checks W0609 and W0610.
1246
- interpret(explicit_ctrlexpr)
1264
+ var = object_to_variable(interpret(explicit_ctrlexpr))
1265
+ notify_variable_value_referred(explicit_ctrlexpr, var)
1266
+ notify_sequence_point_reached(SequencePoint.new(explicit_ctrlexpr))
1247
1267
  end
1248
1268
  end
1249
1269
  ensure
@@ -1616,12 +1636,15 @@ module C #:nodoc:
1616
1636
  checkpoint(node.location)
1617
1637
 
1618
1638
  ctrlexpr = node.condition
1619
- ctrlexpr_var = interpret(ctrlexpr, QUIET)
1639
+ ctrlexpr_var = object_to_variable(interpret(ctrlexpr))
1620
1640
  ctrlexpr_val = value_of(ctrlexpr_var)
1641
+ notify_variable_value_referred(ctrlexpr, ctrlexpr_var)
1642
+ notify_sequence_point_reached(ctrlexpr.subsequent_sequence_point)
1643
+ ctrlexpr = ctrlexpr.to_normalized_logical
1621
1644
 
1622
1645
  then_var = nil
1623
1646
  if ctrlexpr_val.may_be_true?
1624
- branched_eval(ctrlexpr, NARROWING) do
1647
+ branched_eval(ctrlexpr, NARROWING, IMPLICIT_COND) do
1625
1648
  then_var = object_to_variable(interpret(node.then_expression))
1626
1649
  end
1627
1650
  end