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 *, ...);
18 int k
, y
; // non-nested-warning {{unused variable 'k'}}
19 // non-nested-warning@-1 {{unused variable 'y'}}
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;
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;
40 if ((r
= f()) != 0) { // no-warning
41 int y
= r
; // no-warning
42 printf("the error is: %d\n", y
);
50 k
= 2; // non-nested-warning {{never read}}
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;
68 // This is allowed for defensive programming.
74 // This is allowed for defensive programming.
75 p
= (0); // no-warning
80 // This is allowed for defensive programming.
81 p
= (void *)0; // no-warning
86 // This is allowed for defensive programming.
87 p
= (void *)(0); // no-warning
91 // Warn for dead stores in nested expressions.
93 extern int *baz(void);
94 if ((p
= baz())) // nested-warning {{Although the value stored}}
101 x
= x
+ 10; // non-nested-warning {{never read}}
107 x
= 10 + x
; // non-nested-warning {{never read}}
113 return x
++; // non-nested-warning {{never read}}
118 return ((((++x
)))); // no-warning
122 int x
= y
; // non-nested-warning {{unused variable 'x'}}
127 int x
__attribute__((unused
)) = y
; // no-warning
132 // Allow initialiation of scalar variables by parameters as a form of
133 // defensive programming.
134 int x
= y
; // no-warning
139 // Filed with PR 2630. This code should produce no warnings.
142 int b
, c
= b
= a
+ a
;
149 // Filed with PR 2763.
151 int index
, nextLineIndex
;
152 for (index
= 0; index
< count
; index
= nextLineIndex
+ 1) {
153 nextLineIndex
= index
+ 1; // no-warning
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.
167 x
= sizeof(int[x
= (x
|| x
+ 1) * 2]) ? 5 : 8;
168 // nested-warning@-1 {{Although the value stored}}
172 // Self-assignments should not be flagged as dead stores.
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...".
182 int x
= 0; // no-warning
184 x
= 10; // non-nested-warning {{Value stored to 'x' is never read}}
186 x
= 10; // non-nested-warning {{Value stored to 'x' is never read}}
189 x
= 10; // no-warning
191 return (x
= 10); // no-warning
195 int x
= 0; // no-warning
196 return (x
= 10); // nested-warning {{Although the value stored}}
200 int x
= 0; // no-warning
202 x
= 10; // non-nested-warning {{Value stored to 'x' is never read}}
208 x
= 10; // non-nested-warning {{Value stored to 'x' is never read}}
212 int x
= 0; // no-warning
214 x
= 10; // non-nested-warning {{Value stored to 'x' is never read}}
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
;
222 int x
= MyConstant
; // no-warning
227 int f19b(void) { // This case is the same as f19.
228 const int MyConstant
= 0;
229 int x
= MyConstant
; // no-warning
235 int x
= 1; // no-warning
239 void halt(void) __attribute__((noreturn
));
242 x
= x
+ 1; // non-nested-warning {{never read}}
274 x
= x
+ 1; // non-nested-warning {{never read}}
324 0 ?: ((void)y4
, ({ return; }));
329 0 ? (void)x
: ((void)y5
, ({ return; }));
333 1 ? ((void)y6
, ({ return; })) : (void)x
;
339 (void)(0 || (y8
, ({ return; }), 1));
340 // non-nested-warning@-1 {{left operand of comma operator has no effect}}
344 (void)(1 && (y9
, ({ return; }), 1));
345 // non-nested-warning@-1 {{left operand of comma operator has no effect}}
395 __builtin_choose_expr(0, (void)x
, ((void)y19
, ({ return; })));
399 __builtin_choose_expr(1, ((void)y20
, ({ return; })), (void)x
);
405 void f23_aux(const char *s
);
406 void f23(int argc
, char **argv
) {
407 int shouldLog
= (argc
> 1); // no-warning
410 f23_aux("I did too use it!\n");
412 f23_aux("I shouldn't log. Wait.. d'oh!\n");
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");
428 // FIXME: One day this should be reported as dead since 'z = x + y' is dead.
429 int x
= (y
> 2); // no-warning
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;
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.
452 // FIXME: One day this should be reported as dead since 'x' is just overwritten.
453 __block
int x
= (y
> 2); // no-warning
461 __block
int x
= (y
> 2); // no-warning
469 // This example shows that writing to a variable captured by a block means that
470 // it might not be dead.
472 __block
int x
= (y
> 2);
474 void (^foo
)(void) = ^{
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.
486 // FIXME: we should eventually report a dead store here.
487 __block
int x
= (y
> 2);
493 int f26_nestedblocks(void) {
499 k
= 1; // non-nested-warning {{Value stored to 'k' is never read}}
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
)
531 s_rdar8320674
* tw1
= st
->x
;
536 do{ (t
).r
= (*z2
).r
*(*tw1
).r
- (*z2
).i
*(*tw1
).i
; (t
).i
= (*z2
).r
*(*tw1
).i
+ (*z2
).i
*(*tw1
).r
; }while(0);
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);
545 // Avoid dead stores resulting from an assignment (and use) being unreachable.
546 void rdar8405222_aux(int i
);
547 void rdar8405222(void) {
556 // Look through chains of assignments, e.g.: int x = y = 0, when employing
557 // silencing heuristics.
558 int radar11185138_foo(void) {
560 x
= y
= 0; // non-nested-warning {{never read}}
564 int rdar11185138_bar(void) {
566 int x
= y
= 0; // nested-warning {{Although the value stored}}
572 int *radar11185138_baz(void) {
574 x
= y
= 0; // no-warning
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'}}
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'}}
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'}}
629 p
= (getPtr(), (int *)0); // no warning
632 void testVolatile(void) {
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};
648 foo
= rdar34122265_getFoo();
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};
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}};
671 bar
= rdar34122265_getBar();
675 return bar
.x
.x
+ bar
.y
.y
;