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.
- data/ChangeLog +149 -0
- data/MANIFEST +5 -0
- data/NEWS +20 -4
- data/etc/mesg.d/c_builtin/en_US/messages.yml +1 -1
- data/etc/mesg.d/c_builtin/ja_JP/messages.yml +1 -1
- data/etc/mesg.d/core/en_US/messages.yml +1 -1
- data/etc/mesg.d/core/ja_JP/messages.yml +1 -1
- data/features/code_check/W0460.feature +27 -0
- data/features/code_check/W0534.feature +73 -0
- data/features/code_check/W0585.feature +135 -0
- data/features/code_check/W0599.feature +101 -1
- data/features/code_check/W0611.feature +138 -0
- data/features/code_check/W0708.feature +66 -0
- data/features/code_check/W1069.feature +27 -0
- data/features/code_check/W1073.feature +142 -0
- data/lib/adlint/c/ctrlexpr.rb +22 -16
- data/lib/adlint/c/interp.rb +32 -9
- data/lib/adlint/exam/c_builtin/c_check.rb +2597 -183
- data/lib/adlint/exam/c_builtin/c_check_shima.rb +150 -14
- data/lib/adlint/version.rb +2 -2
- data/share/doc/developers_guide_ja.html +3 -3
- data/share/doc/developers_guide_ja.texi +1 -1
- data/share/doc/users_guide_en.html +10 -10
- data/share/doc/users_guide_en.texi +8 -8
- data/share/doc/users_guide_ja.html +10 -10
- data/share/doc/users_guide_ja.texi +8 -8
- metadata +7 -2
@@ -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 |
|
data/lib/adlint/c/ctrlexpr.rb
CHANGED
@@ -71,15 +71,10 @@ module C #:nodoc:
|
|
71
71
|
|
72
72
|
if target_expr
|
73
73
|
new_manip = ValueDomainNarrower.new(@interpreter, target_expr)
|
74
|
-
|
75
|
-
|
76
|
-
|
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
|
-
|
98
|
-
|
99
|
-
|
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
|
data/lib/adlint/c/interp.rb
CHANGED
@@ -981,7 +981,10 @@ module C #:nodoc:
|
|
981
981
|
ctrlexpr_val = ScalarValue.of_arbitrary
|
982
982
|
ctrlexpr = nil
|
983
983
|
else
|
984
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|