Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / Analysis / dead-stores.c
blob00b19b1eb1a1516312e63b01f55dc6d5b5c8a48c
1 // RUN: %check_analyzer_fixit %s %t \
2 // RUN: -Wunused-variable -fblocks -Wno-unreachable-code \
3 // RUN: -analyzer-checker=core,deadcode.DeadStores \
4 // RUN: -analyzer-config deadcode.DeadStores:ShowFixIts=true \
5 // RUN: -analyzer-config \
6 // RUN: deadcode.DeadStores:WarnForDeadNestedAssignments=false \
7 // RUN: -verify=non-nested
9 // RUN: %check_analyzer_fixit %s %t \
10 // RUN: -Wunused-variable -fblocks -Wno-unreachable-code \
11 // RUN: -analyzer-checker=core,deadcode.DeadStores \
12 // RUN: -analyzer-config deadcode.DeadStores:ShowFixIts=true \
13 // RUN: -verify=non-nested,nested
15 extern int printf(const char *, ...);
17 void f1(void) {
18 int k, y; // non-nested-warning {{unused variable 'k'}}
19 // non-nested-warning@-1 {{unused variable 'y'}}
20 int abc = 1;
21 long idx = abc + 3 * 5; // non-nested-warning {{never read}}
22 // non-nested-warning@-1 {{unused variable 'idx'}}
23 // CHECK-FIXES: int abc = 1;
24 // CHECK-FIXES-NEXT: long idx;
27 void f2(void *b) {
28 char *c = (char *)b; // no-warning
29 char *d = b + 1; // non-nested-warning {{never read}}
30 // non-nested-warning@-1 {{unused variable 'd'}}
31 // CHECK-FIXES: char *c = (char *)b;
32 // CHECK-FIXES-NEXT: char *d;
34 printf("%s", c);
37 int f(void);
38 void f3(void) {
39 int r;
40 if ((r = f()) != 0) { // no-warning
41 int y = r; // no-warning
42 printf("the error is: %d\n", y);
46 void f4(int k) {
47 k = 1;
48 if (k)
49 f1();
50 k = 2; // non-nested-warning {{never read}}
53 void f5(void) {
54 int x = 4; // no-warning
55 int *p = &x; // non-nested-warning {{never read}}
56 // non-nested-warning@-1 {{unused variable 'p'}}
57 // CHECK-FIXES: int x = 4;
58 // CHECK-FIXES-NEXT: int *p;
61 int f6(void) {
62 int x = 4;
63 ++x; // no-warning
64 return 1;
67 int f7(int *p) {
68 // This is allowed for defensive programming.
69 p = 0; // no-warning
70 return 1;
73 int f7b(int *p) {
74 // This is allowed for defensive programming.
75 p = (0); // no-warning
76 return 1;
79 int f7c(int *p) {
80 // This is allowed for defensive programming.
81 p = (void *)0; // no-warning
82 return 1;
85 int f7d(int *p) {
86 // This is allowed for defensive programming.
87 p = (void *)(0); // no-warning
88 return 1;
91 // Warn for dead stores in nested expressions.
92 int f8(int *p) {
93 extern int *baz(void);
94 if ((p = baz())) // nested-warning {{Although the value stored}}
95 return 1;
96 return 0;
99 int f9(void) {
100 int x = 4;
101 x = x + 10; // non-nested-warning {{never read}}
102 return 1;
105 int f10(void) {
106 int x = 4;
107 x = 10 + x; // non-nested-warning {{never read}}
108 return 1;
111 int f11(void) {
112 int x = 4;
113 return x++; // non-nested-warning {{never read}}
116 int f11b(void) {
117 int x = 4;
118 return ((((++x)))); // no-warning
121 int f12a(int y) {
122 int x = y; // non-nested-warning {{unused variable 'x'}}
123 return 1;
126 int f12b(int y) {
127 int x __attribute__((unused)) = y; // no-warning
128 return 1;
131 int f12c(int y) {
132 // Allow initialiation of scalar variables by parameters as a form of
133 // defensive programming.
134 int x = y; // no-warning
135 x = 1;
136 return x;
139 // Filed with PR 2630. This code should produce no warnings.
140 int f13(void) {
141 int a = 1;
142 int b, c = b = a + a;
144 if (b > 0)
145 return (0);
146 return (a + b + c);
149 // Filed with PR 2763.
150 int f14(int count) {
151 int index, nextLineIndex;
152 for (index = 0; index < count; index = nextLineIndex + 1) {
153 nextLineIndex = index + 1; // no-warning
154 continue;
156 return index;
159 void f15(unsigned x, unsigned y) {
160 int count = x * y; // no-warning
161 int z[count]; // non-nested-warning {{unused variable 'z'}}
164 // Warn for dead stores in nested expressions.
165 int f16(int x) {
166 x = x * 2;
167 x = sizeof(int[x = (x || x + 1) * 2]) ? 5 : 8;
168 // nested-warning@-1 {{Although the value stored}}
169 return x;
172 // Self-assignments should not be flagged as dead stores.
173 void f17(void) {
174 int x = 1;
175 x = x;
178 // The values of dead stores are only "consumed" in an enclosing expression
179 // what that value is actually used. In other words, don't say "Although the
180 // value stored to 'x' is used...".
181 int f18(void) {
182 int x = 0; // no-warning
183 if (1)
184 x = 10; // non-nested-warning {{Value stored to 'x' is never read}}
185 while (1)
186 x = 10; // non-nested-warning {{Value stored to 'x' is never read}}
187 // unreachable.
189 x = 10; // no-warning
190 while (1);
191 return (x = 10); // no-warning
194 int f18_a(void) {
195 int x = 0; // no-warning
196 return (x = 10); // nested-warning {{Although the value stored}}
199 void f18_b(void) {
200 int x = 0; // no-warning
201 if (1)
202 x = 10; // non-nested-warning {{Value stored to 'x' is never read}}
205 void f18_c(void) {
206 int x = 0;
207 while (1)
208 x = 10; // non-nested-warning {{Value stored to 'x' is never read}}
211 void f18_d(void) {
212 int x = 0; // no-warning
214 x = 10; // non-nested-warning {{Value stored to 'x' is never read}}
215 while (1);
218 // PR 3514: false positive `dead initialization` warning for init to global
219 // http://llvm.org/bugs/show_bug.cgi?id=3514
220 extern const int MyConstant;
221 int f19(void) {
222 int x = MyConstant; // no-warning
223 x = 1;
224 return x;
227 int f19b(void) { // This case is the same as f19.
228 const int MyConstant = 0;
229 int x = MyConstant; // no-warning
230 x = 1;
231 return x;
234 void f20(void) {
235 int x = 1; // no-warning
236 #pragma unused(x)
239 void halt(void) __attribute__((noreturn));
240 int f21(void) {
241 int x = 4;
242 x = x + 1; // non-nested-warning {{never read}}
243 if (1) {
244 halt();
245 (void)x;
247 return 1;
250 int j;
251 void f22(void) {
252 int x = 4;
253 int y1 = 4;
254 int y2 = 4;
255 int y3 = 4;
256 int y4 = 4;
257 int y5 = 4;
258 int y6 = 4;
259 int y7 = 4;
260 int y8 = 4;
261 int y9 = 4;
262 int y10 = 4;
263 int y11 = 4;
264 int y12 = 4;
265 int y13 = 4;
266 int y14 = 4;
267 int y15 = 4;
268 int y16 = 4;
269 int y17 = 4;
270 int y18 = 4;
271 int y19 = 4;
272 int y20 = 4;
274 x = x + 1; // non-nested-warning {{never read}}
275 ++y1;
276 ++y2;
277 ++y3;
278 ++y4;
279 ++y5;
280 ++y6;
281 ++y7;
282 ++y8;
283 ++y9;
284 ++y10;
285 ++y11;
286 ++y12;
287 ++y13;
288 ++y14;
289 ++y15;
290 ++y16;
291 ++y17;
292 ++y18;
293 ++y19;
294 ++y20;
296 switch (j) {
297 case 1:
298 if (0)
299 (void)x;
300 if (1) {
301 (void)y1;
302 return;
304 (void)x;
305 break;
306 case 2:
307 if (0)
308 (void)x;
309 else {
310 (void)y2;
311 return;
313 (void)x;
314 break;
315 case 3:
316 if (1) {
317 (void)y3;
318 return;
319 } else
320 (void)x;
321 (void)x;
322 break;
323 case 4:
324 0 ?: ((void)y4, ({ return; }));
325 (void)x;
326 break;
327 case 5:
328 1 ?: (void)x;
329 0 ? (void)x : ((void)y5, ({ return; }));
330 (void)x;
331 break;
332 case 6:
333 1 ? ((void)y6, ({ return; })) : (void)x;
334 (void)x;
335 break;
336 case 7:
337 (void)(0 && x);
338 (void)y7;
339 (void)(0 || (y8, ({ return; }), 1));
340 // non-nested-warning@-1 {{left operand of comma operator has no effect}}
341 (void)x;
342 break;
343 case 8:
344 (void)(1 && (y9, ({ return; }), 1));
345 // non-nested-warning@-1 {{left operand of comma operator has no effect}}
346 (void)x;
347 break;
348 case 9:
349 (void)(1 || x);
350 (void)y10;
351 break;
352 case 10:
353 while (0) {
354 (void)x;
356 (void)y11;
357 break;
358 case 11:
359 while (1) {
360 (void)y12;
362 (void)x;
363 break;
364 case 12:
365 do {
366 (void)y13;
367 } while (0);
368 (void)y14;
369 break;
370 case 13:
371 do {
372 (void)y15;
373 } while (1);
374 (void)x;
375 break;
376 case 14:
377 for (;;) {
378 (void)y16;
380 (void)x;
381 break;
382 case 15:
383 for (; 1;) {
384 (void)y17;
386 (void)x;
387 break;
388 case 16:
389 for (; 0;) {
390 (void)x;
392 (void)y18;
393 break;
394 case 17:
395 __builtin_choose_expr(0, (void)x, ((void)y19, ({ return; })));
396 (void)x;
397 break;
398 case 19:
399 __builtin_choose_expr(1, ((void)y20, ({ return; })), (void)x);
400 (void)x;
401 break;
405 void f23_aux(const char *s);
406 void f23(int argc, char **argv) {
407 int shouldLog = (argc > 1); // no-warning
409 if (shouldLog)
410 f23_aux("I did too use it!\n");
411 else
412 f23_aux("I shouldn't log. Wait.. d'oh!\n");
413 }();
416 void f23_pos(int argc, char **argv) {
417 int shouldLog = (argc > 1);
418 // non-nested-warning@-1 {{Value stored to 'shouldLog' during its initialization is never read}}
419 // non-nested-warning@-2 {{unused variable 'shouldLog'}}
420 // CHECK-FIXES: void f23_pos(int argc, char **argv) {
421 // CHECK-FIXES-NEXT: int shouldLog;
423 f23_aux("I did too use it!\n");
424 }();
427 void f24_A(int y) {
428 // FIXME: One day this should be reported as dead since 'z = x + y' is dead.
429 int x = (y > 2); // no-warning
431 int z = x + y;
432 // non-nested-warning@-1 {{Value stored to 'z' during its initialization is never read}}
433 // non-nested-warning@-2 {{unused variable 'z'}}
434 // CHECK-FIXES: void f24_A(int y) {
435 // CHECK-FIXES-NEXT: //
436 // CHECK-FIXES-NEXT: int x = (y > 2);
437 // CHECK-FIXES-NEXT: ^{
438 // CHECK-FIXES-NEXT: int z;
439 }();
442 void f24_B(int y) {
443 // FIXME: One day this should be reported as dead since 'x' is just overwritten.
444 __block int x = (y > 2); // no-warning
446 // FIXME: This should eventually be a dead store since it is never read either.
447 x = 5; // no-warning
448 }();
451 int f24_C(int y) {
452 // FIXME: One day this should be reported as dead since 'x' is just overwritten.
453 __block int x = (y > 2); // no-warning
455 x = 5; // no-warning
456 }();
457 return x;
460 int f24_D(int y) {
461 __block int x = (y > 2); // no-warning
463 if (y > 4)
464 x = 5; // no-warning
465 }();
466 return x;
469 // This example shows that writing to a variable captured by a block means that
470 // it might not be dead.
471 int f25(int y) {
472 __block int x = (y > 2);
473 __block int z = 0;
474 void (^foo)(void) = ^{
475 z = x + y;
477 x = 4; // no-warning
478 foo();
479 return z;
482 // This test is mostly the same as 'f25', but shows that the heuristic of
483 // pruning out dead stores for variables that are just marked '__block' is
484 // overly conservative.
485 int f25_b(int y) {
486 // FIXME: we should eventually report a dead store here.
487 __block int x = (y > 2);
488 __block int z = 0;
489 x = 4; // no-warning
490 return z;
493 int f26_nestedblocks(void) {
494 int z;
495 z = 1;
496 __block int y = 0;
498 int k;
499 k = 1; // non-nested-warning {{Value stored to 'k' is never read}}
501 y = z + 1;
502 }();
503 }();
504 return y;
507 // The FOREACH macro in QT uses 'break' statements within statement expressions
508 // placed within the increment code of for loops.
509 void rdar8014335(void) {
510 for (int i = 0 ; i != 10 ; ({ break; })) {
511 for (;; ({ ++i; break; }))
513 // non-nested-warning@-2 {{'break' is bound to current loop, GCC binds it to the enclosing loop}}
514 // Note that the next value stored to 'i' is never executed
515 // because the next statement to be executed is the 'break'
516 // in the increment code of the first loop.
517 i = i * 3; // non-nested-warning {{Value stored to 'i' is never read}}
521 // NullStmts followed by do...while() can lead to disconnected CFG
523 // This previously caused bogus dead-stores warnings because the body of the first do...while was
524 // disconnected from the entry of the function.
525 typedef struct { float r; float i; } s_rdar8320674;
526 typedef struct { s_rdar8320674 x[1]; } s2_rdar8320674;
528 void rdar8320674(s_rdar8320674 *z, unsigned y, s2_rdar8320674 *st, int m)
530 s_rdar8320674 * z2;
531 s_rdar8320674 * tw1 = st->x;
532 s_rdar8320674 t;
533 z2 = z + m;
536 do{ (t).r = (*z2).r*(*tw1).r - (*z2).i*(*tw1).i; (t).i = (*z2).r*(*tw1).i + (*z2).i*(*tw1).r; }while(0);
537 tw1 += y;
538 do { (*z2).r=(*z).r-(t).r; (*z2).i=(*z).i-(t).i; }while(0);
539 do { (*z).r += (t).r; (*z).i += (t).i; }while(0);
540 ++z2;
541 ++z;
542 }while (--m);
545 // Avoid dead stores resulting from an assignment (and use) being unreachable.
546 void rdar8405222_aux(int i);
547 void rdar8405222(void) {
548 const int show = 0;
549 int i = 0;
550 if (show)
551 i = 5; // no-warning
552 if (show)
553 rdar8405222_aux(i);
556 // Look through chains of assignments, e.g.: int x = y = 0, when employing
557 // silencing heuristics.
558 int radar11185138_foo(void) {
559 int x, y;
560 x = y = 0; // non-nested-warning {{never read}}
561 return y;
564 int rdar11185138_bar(void) {
565 int y;
566 int x = y = 0; // nested-warning {{Although the value stored}}
567 x = 2;
568 y = 2;
569 return x + y;
572 int *radar11185138_baz(void) {
573 int *x, *y;
574 x = y = 0; // no-warning
575 return y;
578 int getInt(void);
579 int *getPtr(void);
580 void testBOComma(void) {
581 int x0 = (getInt(), 0); // non-nested-warning {{unused variable 'x0'}}
582 int x1 = (getInt(), getInt());
583 // non-nested-warning@-1 {{Value stored to 'x1' during its initialization is never read}}
584 // non-nested-warning@-2 {{unused variable 'x1'}}
586 int x2 = (getInt(), getInt(), getInt());
587 // non-nested-warning@-1 {{Value stored to 'x2' during its initialization is never read}}
588 // non-nested-warning@-2 {{unused variable 'x2'}}
590 int x3;
591 x3 = (getInt(), getInt(), 0);
592 // non-nested-warning@-1 {{Value stored to 'x3' is never read}}
594 int x4 = (getInt(), (getInt(), 0));
595 // non-nested-warning@-1 {{unused variable 'x4'}}
597 int y;
598 int x5 = (getInt(), (y = 0));
599 // non-nested-warning@-1 {{unused variable 'x5'}}
600 // nested-warning@-2 {{Although the value stored}}
602 int x6 = (getInt(), (y = getInt()));
603 // non-nested-warning@-1 {{Value stored to 'x6' during its initialization is never read}}
604 // non-nested-warning@-2 {{unused variable 'x6'}}
605 // nested-warning@-3 {{Although the value stored}}
607 int x7 = 0, x8 = getInt();
608 // non-nested-warning@-1 {{Value stored to 'x8' during its initialization is never read}}
609 // non-nested-warning@-2 {{unused variable 'x8'}}
610 // non-nested-warning@-3 {{unused variable 'x7'}}
612 int x9 = getInt(), x10 = 0;
613 // non-nested-warning@-1 {{Value stored to 'x9' during its initialization is never read}}
614 // non-nested-warning@-2 {{unused variable 'x9'}}
615 // non-nested-warning@-3 {{unused variable 'x10'}}
617 int m = getInt(), mm, mmm;
618 // non-nested-warning@-1 {{Value stored to 'm' during its initialization is never read}}
619 // non-nested-warning@-2 {{unused variable 'm'}}
620 // non-nested-warning@-3 {{unused variable 'mm'}}
621 // non-nested-warning@-4 {{unused variable 'mmm'}}
623 int n, nn = getInt();
624 // non-nested-warning@-1 {{Value stored to 'nn' during its initialization is never read}}
625 // non-nested-warning@-2 {{unused variable 'n'}}
626 // non-nested-warning@-3 {{unused variable 'nn'}}
628 int *p;
629 p = (getPtr(), (int *)0); // no warning
632 void testVolatile(void) {
633 volatile int v;
634 v = 0; // no warning
637 struct Foo {
638 int x;
639 int y;
642 struct Foo rdar34122265_getFoo(void);
644 int rdar34122265_test(int input) {
645 // This is allowed for defensive programming.
646 struct Foo foo = {0, 0};
647 if (input > 0) {
648 foo = rdar34122265_getFoo();
649 } else {
650 return 0;
652 return foo.x + foo.y;
655 void rdar34122265_test_cast(void) {
656 // This is allowed for defensive programming.
657 struct Foo foo = {0, 0};
658 (void)foo;
661 struct Bar {
662 struct Foo x, y;
665 struct Bar rdar34122265_getBar(void);
667 int rdar34122265_test_nested(int input) {
668 // This is allowed for defensive programming.
669 struct Bar bar = {{0, 0}, {0, 0}};
670 if (input > 0) {
671 bar = rdar34122265_getBar();
672 } else {
673 return 0;
675 return bar.x.x + bar.y.y;