1 // RUN: %clang_cc1 -fsyntax-only -Wloop-analysis -verify -std=c++17 %s
4 bool stop() { return false; }
8 void by_ref(int &value
) { }
9 void by_value(int value
) { }
10 void by_pointer(int *value
) {}
15 for (; s
.keep_running
;) {}
16 for (int i
; i
< 1; ++i
) {}
17 for (int i
; i
< 1; ) {} // expected-warning {{variable 'i' used in loop condition not modified in loop body}}
18 for (int i
; i
< 1; ) { ++i
; }
19 for (int i
; i
< 1; ) { return; }
20 for (int i
; i
< 1; ) { break; }
21 for (int i
; i
< 1; ) { goto exit_loop
; }
23 for (int i
; i
< 1; ) { by_ref(i
); }
24 for (int i
; i
< 1; ) { by_value(i
); } // expected-warning {{variable 'i' used in loop condition not modified in loop body}}
25 for (int i
; i
< 1; ) { by_pointer(&i
); }
27 for (int i
; i
< 1; ++i
)
28 for (int j
; j
< 1; ++j
)
30 for (int i
; i
< 1; ++i
)
31 for (int j
; j
< 1; ++i
) // expected-warning {{variable 'j' used in loop condition not modified in loop body}}
33 for (int i
; i
< 1; ++i
)
34 for (int j
; i
< 1; ++j
) // expected-warning {{variable 'i' used in loop condition not modified in loop body}}
37 for (int *i
, *j
; i
< j
; ++i
) {}
38 for (int *i
, *j
; i
< j
;) {} // expected-warning {{variables 'i' and 'j' used in loop condition not modified in loop body}}
40 // Dereferencing pointers is ignored for now.
49 for (; i
; ) {} // expected-warning {{variable 'i' used in loop condition not modified in loop body}}
50 for (; i
; ) { i
= 5; }
52 // Testing BinaryOperator
53 for (; i
< j
; ) {} // expected-warning {{variables 'i' and 'j' used in loop condition not modified in loop body}}
54 for (; i
< j
; ) { i
= 5; }
55 for (; i
< j
; ) { j
= 5; }
57 // Testing IntegerLiteral
58 for (; i
< 5; ) {} // expected-warning {{variable 'i' used in loop condition not modified in loop body}}
59 for (; i
< 5; ) { i
= 5; }
61 // Testing FloatingLiteral
62 for (; i
< 5.0; ) {} // expected-warning {{variable 'i' used in loop condition not modified in loop body}}
63 for (; i
< 5.0; ) { i
= 5; }
65 // Testing CharacterLiteral
66 for (; i
== 'a'; ) {} // expected-warning {{variable 'i' used in loop condition not modified in loop body}}
67 for (; i
== 'a'; ) { i
= 5; }
69 // Testing CXXBoolLiteralExpr
70 for (; i
== true; ) {} // expected-warning {{variable 'i' used in loop condition not modified in loop body}}
71 for (; i
== true; ) { i
= 5; }
73 // Testing GNUNullExpr
74 for (; ptr
== __null
; ) {} // expected-warning {{variable 'ptr' used in loop condition not modified in loop body}}
75 for (; ptr
== __null
; ) { ptr
= &i
; }
77 // Testing UnaryOperator
78 for (; -i
> 5; ) {} // expected-warning {{variable 'i' used in loop condition not modified in loop body}}
79 for (; -i
> 5; ) { ++i
; }
81 // Testing ImaginaryLiteral
82 for (; i
!= 3i
; ) {} // expected-warning {{variable 'i' used in loop condition not modified in loop body}}
83 for (; i
!= 3i
; ) { ++i
; }
85 // Testing ConditionalOperator
86 for (; i
? j
: k
; ) {} // expected-warning {{variables 'i', 'j', and 'k' used in loop condition not modified in loop body}}
87 for (; i
? j
: k
; ) { ++i
; }
88 for (; i
? j
: k
; ) { ++j
; }
89 for (; i
? j
: k
; ) { ++k
; }
90 for (; i
; ) { j
= i
? i
: i
; } // expected-warning {{variable 'i' used in loop condition not modified in loop body}}
91 for (; i
; ) { j
= (i
= 1) ? i
: i
; }
92 for (; i
; ) { j
= i
? i
: ++i
; }
94 // Testing BinaryConditionalOperator
95 for (; i
?: j
; ) {} // expected-warning {{variables 'i' and 'j' used in loop condition not modified in loop body}}
96 for (; i
?: j
; ) { ++i
; }
97 for (; i
?: j
; ) { ++j
; }
98 for (; i
; ) { j
= i
?: i
; } // expected-warning {{variable 'i' used in loop condition not modified in loop body}}
101 for (; (i
); ) { } // expected-warning {{variable 'i' used in loop condition not modified in loop body}}
102 for (; (i
); ) { ++i
; }
104 // Testing non-evaluated variables
105 for (; i
< sizeof(j
); ) { } // expected-warning {{variable 'i' used in loop condition not modified in loop body}}
106 for (; i
< sizeof(j
); ) { ++j
; } // expected-warning {{variable 'i' used in loop condition not modified in loop body}}
107 for (; i
< sizeof(j
); ) { ++i
; }
110 // False positive and how to silence.
114 for (;x
<5;) { *ptr
= 6; } // expected-warning {{variable 'x' used in loop condition not modified in loop body}}
122 // Check ordering and printing of variables. Max variables is currently 4.
124 int a
, b
, c
, d
, e
, f
;
125 for (; a
;); // expected-warning {{variable 'a' used in loop condition not modified in loop body}}
126 for (; a
+ b
;); // expected-warning {{variables 'a' and 'b' used in loop condition not modified in loop body}}
127 for (; a
+ b
+ c
;); // expected-warning {{variables 'a', 'b', and 'c' used in loop condition not modified in loop body}}
128 for (; a
+ b
+ c
+ d
;); // expected-warning {{variables 'a', 'b', 'c', and 'd' used in loop condition not modified in loop body}}
129 for (; a
+ b
+ c
+ d
+ e
;); // expected-warning {{variables used in loop condition not modified in loop body}}
130 for (; a
+ b
+ c
+ d
+ e
+ f
;); // expected-warning {{variables used in loop condition not modified in loop body}}
131 for (; a
+ c
+ d
+ b
;); // expected-warning {{variables 'a', 'c', 'd', and 'b' used in loop condition not modified in loop body}}
132 for (; d
+ c
+ b
+ a
;); // expected-warning {{variables 'd', 'c', 'b', and 'a' used in loop condition not modified in loop body}}
135 // Ensure that the warning doesn't fail when lots of variables are used
136 // in the conditional.
138 for (int a
; a
+a
+a
+a
+a
+a
+a
+a
+a
+a
;); // \
139 // expected-warning {{variable 'a' used in loop condition not modified in loop body}}
140 for (int a
; a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
;); // \
141 // expected-warning {{variable 'a' used in loop condition not modified in loop body}}
142 for (int a
; a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
;); // \
143 // expected-warning {{variable 'a' used in loop condition not modified in loop body}}
144 for (int a
; a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
+a
;);//\
145 // expected-warning {{variable 'a' used in loop condition not modified in loop body}}
148 // Ignore global variables and static variables.
158 for (;;i
++) { // expected-note{{incremented here}}
160 i
++; // expected-warning{{incremented both}}
162 for (;;i
++) { // expected-note{{incremented here}}
164 ++i
; // expected-warning{{incremented both}}
166 for (;;++i
) { // expected-note{{incremented here}}
168 i
++; // expected-warning{{incremented both}}
170 for (;;++i
) { // expected-note{{incremented here}}
171 ++i
; // expected-warning{{incremented both}}
174 for (;;i
--) { // expected-note{{decremented here}}
176 i
--; // expected-warning{{decremented both}}
178 for (;;i
--) { // expected-note{{decremented here}}
180 --i
; // expected-warning{{decremented both}}
182 for (;;--i
) { // expected-note{{decremented here}}
184 i
--; // expected-warning{{decremented both}}
186 for (;;--i
) { // expected-note{{decremented here}}
187 --i
; // expected-warning{{decremented both}}
190 // Don't warn when loop is only one statement.
196 // Don't warn when loop has continue statement.
206 // But do warn if the continue is in a nested loop.
207 for (;;i
--) { // expected-note{{decremented here}}
208 for (int j
= 0; j
< 10; ++j
) continue;
209 i
--; // expected-warning{{decremented both}}
214 iterator
operator++() { return *this; }
215 iterator
operator++(int) { return *this; }
216 iterator
operator--() { return *this; }
217 iterator
operator--(int) { return *this; }
221 for (;;i
++) { // expected-note{{incremented here}}
223 i
++; // expected-warning{{incremented both}}
225 for (;;i
++) { // expected-note{{incremented here}}
227 ++i
; // expected-warning{{incremented both}}
229 for (;;++i
) { // expected-note{{incremented here}}
231 i
++; // expected-warning{{incremented both}}
233 for (;;++i
) { // expected-note{{incremented here}}
234 ++i
; // expected-warning{{incremented both}}
237 for (;;i
--) { // expected-note{{decremented here}}
239 i
--; // expected-warning{{decremented both}}
241 for (;;i
--) { // expected-note{{decremented here}}
243 --i
; // expected-warning{{decremented both}}
245 for (;;--i
) { // expected-note{{decremented here}}
247 i
--; // expected-warning{{decremented both}}
249 for (;;--i
) { // expected-note{{decremented here}}
250 --i
; // expected-warning{{decremented both}}
253 // Don't warn when loop is only one statement.
259 // Don't warn when loop has continue statement.
269 // But do warn if the continue is in a nested loop.
270 for (;;i
--) { // expected-note{{decremented here}}
271 for (int j
= 0; j
< 10; ++j
) continue;
272 i
--; // expected-warning{{decremented both}}
278 // Don't warn when variable is defined by the loop condition.
279 for (int i
= 0; int x
= f(i
); ++i
) {}
282 // Don't warn when decomposition variables are in the loop condition.
283 // TODO: BindingDecl's which make a copy should warn.
285 int arr
[] = {1, 2, 3};
286 for (auto[i
, j
, k
] = arr
;;) { }
287 for (auto[i
, j
, k
] = arr
; i
< j
; ++i
, ++j
) { }
289 for (auto[i
, j
, k
] = arr
; i
;) { }
290 for (auto[i
, j
, k
] = arr
; i
< j
;) { }
291 for (auto[i
, j
, k
] = arr
; i
< j
; ++arr
[0]) { }
294 for (auto[i
, j
, k
] = arr
; a
< b
;) { } // expected-warning{{variables 'a' and 'b' used in loop condition not modified in loop body}}
295 for (auto[i
, j
, k
] = arr
; a
< b
; ++a
) { }
297 for (auto [i
, j
, k
] = arr
; i
< a
;) { }
298 for (auto[i
, j
, k
] = arr
; i
< a
; ++a
) { }
299 for (auto[i
, j
, k
] = arr
; i
< a
; ++i
) { }
300 for (auto[i
, j
, k
] = arr
; i
< a
; ++arr
[0]) { }