1 | // RUN: %clang_cc1 -std=gnu++11 -Wsometimes-uninitialized -verify %s |
2 | // RUN: %clang_cc1 -std=gnu++11 -Wsometimes-uninitialized -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s |
3 | |
4 | bool maybe(); |
5 | |
6 | int test_if_false(bool b) { |
7 | int x; // expected-note {{variable}} |
8 | if (b) // expected-warning {{whenever 'if' condition is false}} \ |
9 | // expected-note {{remove the 'if' if its condition is always true}} |
10 | x = 1; |
11 | return x; // expected-note {{uninitialized use}} |
12 | } |
13 | |
14 | // CHECK: fix-it:"{{.*}}":{8:3-10:5}:"" |
15 | // CHECK: fix-it:"{{.*}}":{7:8-7:8}:" = 0" |
16 | |
17 | |
18 | int test_if_true(bool b) { |
19 | int x; // expected-note {{variable}} |
20 | if (b) {} // expected-warning {{whenever 'if' condition is true}} \ |
21 | // expected-note {{remove the 'if' if its condition is always false}} |
22 | else x = 1; |
23 | return x; // expected-note {{uninitialized use}} |
24 | } |
25 | |
26 | // CHECK: fix-it:"{{.*}}":{20:3-22:8}:"" |
27 | // CHECK: fix-it:"{{.*}}":{19:8-19:8}:" = 0" |
28 | |
29 | |
30 | int test_while_false(bool b) { |
31 | int x; // expected-note {{variable}} |
32 | while (b) { // expected-warning {{whenever 'while' loop exits because its condition is false}} \ |
33 | // expected-note {{remove the condition if it is always true}} |
34 | if (maybe()) { |
35 | x = 1; |
36 | break; |
37 | } |
38 | }; |
39 | return x; // expected-note {{uninitialized use}} |
40 | } |
41 | |
42 | // CHECK: fix-it:"{{.*}}":{32:10-32:11}:"true" |
43 | // CHECK: fix-it:"{{.*}}":{31:8-31:8}:" = 0" |
44 | |
45 | |
46 | int test_while_true(bool b) { |
47 | int x; // expected-note {{variable}} |
48 | while (b) { // expected-warning {{whenever 'while' loop is entered}} \ |
49 | // expected-note {{remove the condition if it is always false}} |
50 | label: |
51 | return x; // expected-note {{uninitialized use}} |
52 | } |
53 | x = 0; |
54 | goto label; |
55 | } |
56 | |
57 | // CHECK: fix-it:"{{.*}}":{48:10-48:11}:"false" |
58 | // CHECK: fix-it:"{{.*}}":{47:8-47:8}:" = 0" |
59 | |
60 | |
61 | int test_do_while_false(bool b) { |
62 | int x; // expected-note {{variable}} |
63 | do { |
64 | if (maybe()) { |
65 | x = 1; |
66 | break; |
67 | } |
68 | } while (b); // expected-warning {{whenever 'do' loop exits because its condition is false}} \ |
69 | // expected-note {{remove the condition if it is always true}} |
70 | return x; // expected-note {{uninitialized use}} |
71 | } |
72 | |
73 | // CHECK: fix-it:"{{.*}}":{68:12-68:13}:"true" |
74 | // CHECK: fix-it:"{{.*}}":{62:8-62:8}:" = 0" |
75 | |
76 | |
77 | int test_do_while_true(bool b) { |
78 | int x; // expected-note {{variable}} |
79 | goto label2; |
80 | do { |
81 | label1: |
82 | return x; // expected-note {{uninitialized use}} |
83 | label2: ; |
84 | } while (b); // expected-warning {{whenever 'do' loop condition is true}} \ |
85 | // expected-note {{remove the condition if it is always false}} |
86 | x = 0; |
87 | goto label1; |
88 | } |
89 | |
90 | // CHECK: fix-it:"{{.*}}":{84:12-84:13}:"false" |
91 | // CHECK: fix-it:"{{.*}}":{78:8-78:8}:" = 0" |
92 | |
93 | |
94 | int test_for_false(int k) { |
95 | int x; // expected-note {{variable}} |
96 | for (int n = 0; |
97 | n < k; // expected-warning {{whenever 'for' loop exits because its condition is false}} \ |
98 | // expected-note {{remove the condition if it is always true}} |
99 | ++n) { |
100 | if (maybe()) { |
101 | x = n; |
102 | break; |
103 | } |
104 | } |
105 | return x; // expected-note {{uninitialized use}} |
106 | } |
107 | |
108 | // CHECK: fix-it:"{{.*}}":{97:8-97:13}:"" |
109 | // CHECK: fix-it:"{{.*}}":{95:8-95:8}:" = 0" |
110 | |
111 | |
112 | int test_for_true(int k) { |
113 | int x; // expected-note {{variable}} |
114 | int n = 0; |
115 | for (; |
116 | n < k; // expected-warning {{whenever 'for' loop is entered}} \ |
117 | // expected-note {{remove the condition if it is always false}} |
118 | ++n) { |
119 | label: |
120 | return x; // expected-note {{uninitialized use}} |
121 | } |
122 | x = 1; |
123 | goto label; |
124 | } |
125 | |
126 | // CHECK: fix-it:"{{.*}}":{116:8-116:13}:"false" |
127 | // CHECK: fix-it:"{{.*}}":{113:8-113:8}:" = 0" |
128 | |
129 | |
130 | int test_for_range_false(int k) { |
131 | int arr[3] = { 1, 2, 3 }; |
132 | int x; |
133 | for (int &a : arr) { // no-warning, condition was not explicitly specified |
134 | if (a == k) { |
135 | x = &a - arr; |
136 | break; |
137 | } |
138 | } |
139 | return x; |
140 | } |
141 | |
142 | |
143 | |
144 | |
145 | |
146 | int test_for_range_true(int k) { |
147 | int arr[3] = { 1, 2, 3 }; |
148 | int x; // expected-note {{variable}} |
149 | for (int &a : arr) { // expected-warning {{variable 'x' is used uninitialized whenever 'for' loop is entered}} |
150 | goto label; |
151 | } |
152 | x = 0; |
153 | label: |
154 | return x; // expected-note {{uninitialized use}} |
155 | } |
156 | |
157 | |
158 | |
159 | |
160 | |
161 | int test_conditional_false(int k) { |
162 | int x; // expected-note {{variable}} |
163 | (void)( |
164 | maybe() // expected-warning {{whenever '?:' condition is false}} \ |
165 | // expected-note {{remove the '?:' if its condition is always true}} |
166 | ? x = 1 : 0); |
167 | return x; // expected-note {{uninitialized use}} |
168 | } |
169 | |
170 | // CHECK: fix-it:"{{.*}}":{164:7-166:9}:"" |
171 | // CHECK: fix-it:"{{.*}}":{166:14-166:18}:"" |
172 | // CHECK: fix-it:"{{.*}}":{162:8-162:8}:" = 0" |
173 | |
174 | int test_conditional_true(int k) { |
175 | int x; // expected-note {{variable}} |
176 | (void)( |
177 | maybe() // expected-warning {{whenever '?:' condition is true}} \ |
178 | // expected-note {{remove the '?:' if its condition is always false}} |
179 | ? 0 : x = 1); |
180 | return x; // expected-note {{uninitialized use}} |
181 | } |
182 | |
183 | // CHECK: fix-it:"{{.*}}":{177:7-179:13}:"" |
184 | // CHECK: fix-it:"{{.*}}":{175:8-175:8}:" = 0" |
185 | |
186 | |
187 | int test_logical_and_false(int k) { |
188 | int x; // expected-note {{variable}} |
189 | maybe() // expected-warning {{whenever '&&' condition is false}} \ |
190 | // expected-note {{remove the '&&' if its condition is always true}} |
191 | && (x = 1); |
192 | return x; // expected-note {{uninitialized use}} |
193 | } |
194 | |
195 | // CHECK: fix-it:"{{.*}}":{189:3-191:10}:"" |
196 | // CHECK: fix-it:"{{.*}}":{188:8-188:8}:" = 0" |
197 | |
198 | |
199 | int test_logical_and_true(int k) { |
200 | int x; // expected-note {{variable}} |
201 | maybe() // expected-warning {{whenever '&&' condition is true}} \ |
202 | // expected-note {{remove the '&&' if its condition is always false}} |
203 | && ({ goto skip_init; 0; }); |
204 | x = 1; |
205 | skip_init: |
206 | return x; // expected-note {{uninitialized use}} |
207 | } |
208 | |
209 | // CHECK: fix-it:"{{.*}}":{201:3-203:34}:"false" |
210 | // CHECK: fix-it:"{{.*}}":{200:8-200:8}:" = 0" |
211 | |
212 | |
213 | int test_logical_or_false(int k) { |
214 | int x; // expected-note {{variable}} |
215 | maybe() // expected-warning {{whenever '||' condition is false}} \ |
216 | // expected-note {{remove the '||' if its condition is always true}} |
217 | || ({ goto skip_init; 0; }); |
218 | x = 1; |
219 | skip_init: |
220 | return x; // expected-note {{uninitialized use}} |
221 | } |
222 | |
223 | // CHECK: fix-it:"{{.*}}":{215:3-217:34}:"true" |
224 | // CHECK: fix-it:"{{.*}}":{214:8-214:8}:" = 0" |
225 | |
226 | |
227 | int test_logical_or_true(int k) { |
228 | int x; // expected-note {{variable}} |
229 | maybe() // expected-warning {{whenever '||' condition is true}} \ |
230 | // expected-note {{remove the '||' if its condition is always false}} |
231 | || (x = 1); |
232 | return x; // expected-note {{uninitialized use}} |
233 | } |
234 | |
235 | // CHECK: fix-it:"{{.*}}":{229:3-231:10}:"" |
236 | // CHECK: fix-it:"{{.*}}":{228:8-228:8}:" = 0" |
237 | |
238 | |
239 | int test_switch_case(int k) { |
240 | int x; // expected-note {{variable}} |
241 | switch (k) { |
242 | case 0: |
243 | x = 0; |
244 | break; |
245 | case 1: // expected-warning {{whenever switch case is taken}} |
246 | break; |
247 | } |
248 | return x; // expected-note {{uninitialized use}} |
249 | } |
250 | |
251 | // CHECK: fix-it:"{{.*}}":{240:8-240:8}:" = 0" |
252 | |
253 | |
254 | |
255 | int test_switch_default(int k) { |
256 | int x; // expected-note {{variable}} |
257 | switch (k) { |
258 | case 0: |
259 | x = 0; |
260 | break; |
261 | case 1: |
262 | x = 1; |
263 | break; |
264 | default: // expected-warning {{whenever switch default is taken}} |
265 | break; |
266 | } |
267 | return x; // expected-note {{uninitialized use}} |
268 | } |
269 | |
270 | // CHECK: fix-it:"{{.*}}":{256:8-256:8}:" = 0" |
271 | |
272 | |
273 | |
274 | int test_switch_suppress_1(int k) { |
275 | int x; |
276 | switch (k) { |
277 | case 0: |
278 | x = 0; |
279 | break; |
280 | case 1: |
281 | x = 1; |
282 | break; |
283 | } |
284 | return x; // no-warning |
285 | } |
286 | |
287 | |
288 | |
289 | |
290 | |
291 | int test_switch_suppress_2(int k) { |
292 | int x; |
293 | switch (k) { |
294 | case 0: |
295 | case 1: |
296 | switch (k) { |
297 | case 0: |
298 | return 0; |
299 | case 1: |
300 | return 1; |
301 | } |
302 | case 2: |
303 | case 3: |
304 | x = 1; |
305 | } |
306 | return x; // no-warning |
307 | } |
308 | |
309 | |
310 | |
311 | |
312 | |
313 | int test_multiple_notes(int k) { |
314 | int x; // expected-note {{variable}} |
315 | if (k > 0) { |
316 | if (k == 5) |
317 | x = 1; |
318 | else if (k == 2) // expected-warning {{whenever 'if' condition is false}} \ |
319 | // expected-note {{remove the 'if' if its condition is always true}} |
320 | x = 2; |
321 | } else { |
322 | if (k == -5) |
323 | x = 3; |
324 | else if (k == -2) // expected-warning {{whenever 'if' condition is false}} \ |
325 | // expected-note {{remove the 'if' if its condition is always true}} |
326 | x = 4; |
327 | } |
328 | return x; // expected-note 2{{uninitialized use}} |
329 | } |
330 | |
331 | // CHECK: fix-it:"{{.*}}":{324:10-326:7}:"" |
332 | // CHECK: fix-it:"{{.*}}":{318:10-320:7}:"" |
333 | // CHECK: fix-it:"{{.*}}":{314:8-314:8}:" = 0" |
334 | |
335 | int test_no_false_positive_1(int k) { |
336 | int x; |
337 | if (k) |
338 | x = 5; |
339 | while (!k) |
340 | maybe(); |
341 | return x; |
342 | } |
343 | |
344 | |
345 | |
346 | |
347 | |
348 | int test_no_false_positive_2() { |
349 | int x; |
350 | bool b = false; |
351 | if (maybe()) { |
352 | x = 5; |
353 | b = true; |
354 | } |
355 | return b ? x : 0; |
356 | } |
357 | |
358 | |
359 | |
360 | |
361 | |
362 | void test_null_pred_succ() { |
363 | int x; // expected-note {{variable}} expected-warning {{used uninitialized whenever function 'test_null_pred_succ' is called}} |
364 | if (0) |
365 | foo: x = 0; |
366 | if (x) // expected-note {{use}} |
367 | goto foo; |
368 | } |
369 | |
370 | |
371 | |
372 | |
373 | void foo(); |
374 | int PR13360(bool b) { |
375 | int x; // expected-note {{variable}} |
376 | if (b) { // expected-warning {{variable 'x' is used uninitialized whenever 'if' condition is true}} expected-note {{remove}} |
377 | do { |
378 | foo(); |
379 | } while (0); |
380 | } else { |
381 | x = 1; |
382 | } |
383 | return x; // expected-note {{uninitialized use occurs here}} |
384 | } |
385 | |
386 | // CHECK: fix-it:"{{.*}}":{376:3-380:10}:"" |
387 | // CHECK: fix-it:"{{.*}}":{375:8-375:8}:" = 0" |
388 | |
389 | void test_jump_init() { |
390 | goto later; |
391 | int x; // expected-note {{variable}} expected-warning {{used uninitialized whenever function 'test_jump_init'}} |
392 | later: |
393 | while (x) x = 0; // expected-note {{use}} |
394 | } |
395 | |
396 | void PR16054() { |
397 | int x; // expected-note {{variable}} expected-warning {{used uninitialized whenever function 'PR16054}} |
398 | while (x != 0) { // expected-note {{use}} |
399 | (void)&x; |
400 | } |
401 | } |
402 | |
403 | void test_loop_uninit() { |
404 | for (int n = 0; n < 10; ++n) { |
405 | int k; // expected-warning {{variable 'k' is used uninitialized whenever its declaration is reached}} expected-note {{variable}} |
406 | do { |
407 | k = k + 1; // expected-note {{use}} |
408 | } while (k != 5); |
409 | } |
410 | } |
411 | |
412 | // FIXME: We should warn here, because the variable is used uninitialized |
413 | // the first time we encounter the use. |
414 | void test_loop_with_assignment() { |
415 | double d; |
416 | for (int n = 0; n < 10; ++n) { |
417 | d = d + n; |
418 | } |
419 | } |
420 | |
421 | // FIXME: We should warn here, because the variable is used uninitialized |
422 | // the first time we encounter the use. |
423 | void test_loop_with_ref_bind() { |
424 | double d; |
425 | for (int n = 0; n < 10; ++n) { |
426 | d += n; |
427 | const double &r = d; |
428 | } |
429 | } |
430 | |