adlint 2.6.2 → 2.6.10

Sign up to get free protection for your applications and to get access to all the features.
@@ -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