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
16 int k
, y
; // non-nested-warning {{unused variable 'k'}}
17 // non-nested-warning@-1 {{unused variable 'y'}}
19 long idx
= abc
+ 3 * 5; // non-nested-warning {{never read}}
20 // non-nested-warning@-1 {{unused variable 'idx'}}
21 // CHECK-FIXES: int abc = 1;
22 // CHECK-FIXES-NEXT: long idx;
26 char *c
= (char *)b
; // no-warning
27 char *d
= b
+ 1; // non-nested-warning {{never read}}
28 // non-nested-warning@-1 {{unused variable 'd'}}
29 // CHECK-FIXES: char *c = (char *)b;
30 // CHECK-FIXES-NEXT: char *d;
33 // non-nested-warning@-1 {{implicitly declaring library function 'printf' with type 'int (const char *, ...)'}}
34 // non-nested-note@-2 {{include the header <stdio.h> or explicitly provide a declaration for 'printf'}}
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 // Test case for <rdar://problem/6248086>
160 void f15(unsigned x
, unsigned y
) {
161 int count
= x
* y
; // no-warning
162 int z
[count
]; // non-nested-warning {{unused variable 'z'}}
165 // Warn for dead stores in nested expressions.
168 x
= sizeof(int[x
= (x
|| x
+ 1) * 2]) ? 5 : 8;
169 // nested-warning@-1 {{Although the value stored}}
173 // Self-assignments should not be flagged as dead stores.
179 // <rdar://problem/6506065>
180 // The values of dead stores are only "consumed" in an enclosing expression
181 // what that value is actually used. In other words, don't say "Although the
182 // value stored to 'x' is used...".
184 int x
= 0; // no-warning
186 x
= 10; // non-nested-warning {{Value stored to 'x' is never read}}
188 x
= 10; // non-nested-warning {{Value stored to 'x' is never read}}
191 x
= 10; // no-warning
193 return (x
= 10); // no-warning
197 int x
= 0; // no-warning
198 return (x
= 10); // nested-warning {{Although the value stored}}
202 int x
= 0; // no-warning
204 x
= 10; // non-nested-warning {{Value stored to 'x' is never read}}
210 x
= 10; // non-nested-warning {{Value stored to 'x' is never read}}
214 int x
= 0; // no-warning
216 x
= 10; // non-nested-warning {{Value stored to 'x' is never read}}
220 // PR 3514: false positive `dead initialization` warning for init to global
221 // http://llvm.org/bugs/show_bug.cgi?id=3514
222 extern const int MyConstant
;
224 int x
= MyConstant
; // no-warning
229 int f19b(void) { // This case is the same as f19.
230 const int MyConstant
= 0;
231 int x
= MyConstant
; // no-warning
237 int x
= 1; // no-warning
241 void halt(void) __attribute__((noreturn
));
244 x
= x
+ 1; // non-nested-warning {{never read}}
276 x
= x
+ 1; // non-nested-warning {{never read}}
326 0 ?: ((void)y4
, ({ return; }));
331 0 ? (void)x
: ((void)y5
, ({ return; }));
335 1 ? ((void)y6
, ({ return; })) : (void)x
;
341 (void)(0 || (y8
, ({ return; }), 1));
342 // non-nested-warning@-1 {{left operand of comma operator has no effect}}
346 (void)(1 && (y9
, ({ return; }), 1));
347 // non-nested-warning@-1 {{left operand of comma operator has no effect}}
397 __builtin_choose_expr(0, (void)x
, ((void)y19
, ({ return; })));
401 __builtin_choose_expr(1, ((void)y20
, ({ return; })), (void)x
);
407 void f23_aux(const char *s
);
408 void f23(int argc
, char **argv
) {
409 int shouldLog
= (argc
> 1); // no-warning
412 f23_aux("I did too use it!\n");
414 f23_aux("I shouldn't log. Wait.. d'oh!\n");
418 void f23_pos(int argc
, char **argv
) {
419 int shouldLog
= (argc
> 1);
420 // non-nested-warning@-1 {{Value stored to 'shouldLog' during its initialization is never read}}
421 // non-nested-warning@-2 {{unused variable 'shouldLog'}}
422 // CHECK-FIXES: void f23_pos(int argc, char **argv) {
423 // CHECK-FIXES-NEXT: int shouldLog;
425 f23_aux("I did too use it!\n");
430 // FIXME: One day this should be reported as dead since 'z = x + y' is dead.
431 int x
= (y
> 2); // no-warning
434 // non-nested-warning@-1 {{Value stored to 'z' during its initialization is never read}}
435 // non-nested-warning@-2 {{unused variable 'z'}}
436 // CHECK-FIXES: void f24_A(int y) {
437 // CHECK-FIXES-NEXT: //
438 // CHECK-FIXES-NEXT: int x = (y > 2);
439 // CHECK-FIXES-NEXT: ^{
440 // CHECK-FIXES-NEXT: int z;
445 // FIXME: One day this should be reported as dead since 'x' is just overwritten.
446 __block
int x
= (y
> 2); // no-warning
448 // FIXME: This should eventually be a dead store since it is never read either.
454 // FIXME: One day this should be reported as dead since 'x' is just overwritten.
455 __block
int x
= (y
> 2); // no-warning
463 __block
int x
= (y
> 2); // no-warning
471 // This example shows that writing to a variable captured by a block means that
472 // it might not be dead.
474 __block
int x
= (y
> 2);
476 void (^foo
)(void) = ^{
484 // This test is mostly the same as 'f25', but shows that the heuristic of
485 // pruning out dead stores for variables that are just marked '__block' is
486 // overly conservative.
488 // FIXME: we should eventually report a dead store here.
489 __block
int x
= (y
> 2);
495 int f26_nestedblocks(void) {
501 k
= 1; // non-nested-warning {{Value stored to 'k' is never read}}
509 // The FOREACH macro in QT uses 'break' statements within statement expressions
510 // placed within the increment code of for loops.
511 void rdar8014335(void) {
512 for (int i
= 0 ; i
!= 10 ; ({ break; })) {
513 for (;; ({ ++i
; break; }))
515 // non-nested-warning@-2 {{'break' is bound to current loop, GCC binds it to the enclosing loop}}
516 // Note that the next value stored to 'i' is never executed
517 // because the next statement to be executed is the 'break'
518 // in the increment code of the first loop.
519 i
= i
* 3; // non-nested-warning {{Value stored to 'i' is never read}}
523 // <rdar://problem/8320674> NullStmts followed by do...while() can lead to disconnected CFG
525 // This previously caused bogus dead-stores warnings because the body of the first do...while was
526 // disconnected from the entry of the function.
527 typedef struct { float r
; float i
; } s_rdar8320674
;
528 typedef struct { s_rdar8320674 x
[1]; } s2_rdar8320674
;
530 void rdar8320674(s_rdar8320674
*z
, unsigned y
, s2_rdar8320674
*st
, int m
)
533 s_rdar8320674
* tw1
= st
->x
;
538 do{ (t
).r
= (*z2
).r
*(*tw1
).r
- (*z2
).i
*(*tw1
).i
; (t
).i
= (*z2
).r
*(*tw1
).i
+ (*z2
).i
*(*tw1
).r
; }while(0);
540 do { (*z2
).r
=(*z
).r
-(t
).r
; (*z2
).i
=(*z
).i
-(t
).i
; }while(0);
541 do { (*z
).r
+= (t
).r
; (*z
).i
+= (t
).i
; }while(0);
547 // Avoid dead stores resulting from an assignment (and use) being unreachable.
548 void rdar8405222_aux(int i
);
549 void rdar8405222(void) {
558 // Look through chains of assignments, e.g.: int x = y = 0, when employing
559 // silencing heuristics.
560 int radar11185138_foo(void) {
562 x
= y
= 0; // non-nested-warning {{never read}}
566 int rdar11185138_bar(void) {
568 int x
= y
= 0; // nested-warning {{Although the value stored}}
574 int *radar11185138_baz(void) {
576 x
= y
= 0; // no-warning
582 void testBOComma(void) {
583 int x0
= (getInt(), 0); // non-nested-warning {{unused variable 'x0'}}
584 int x1
= (getInt(), getInt());
585 // non-nested-warning@-1 {{Value stored to 'x1' during its initialization is never read}}
586 // non-nested-warning@-2 {{unused variable 'x1'}}
588 int x2
= (getInt(), getInt(), getInt());
589 // non-nested-warning@-1 {{Value stored to 'x2' during its initialization is never read}}
590 // non-nested-warning@-2 {{unused variable 'x2'}}
593 x3
= (getInt(), getInt(), 0);
594 // non-nested-warning@-1 {{Value stored to 'x3' is never read}}
596 int x4
= (getInt(), (getInt(), 0));
597 // non-nested-warning@-1 {{unused variable 'x4'}}
600 int x5
= (getInt(), (y
= 0));
601 // non-nested-warning@-1 {{unused variable 'x5'}}
602 // nested-warning@-2 {{Although the value stored}}
604 int x6
= (getInt(), (y
= getInt()));
605 // non-nested-warning@-1 {{Value stored to 'x6' during its initialization is never read}}
606 // non-nested-warning@-2 {{unused variable 'x6'}}
607 // nested-warning@-3 {{Although the value stored}}
609 int x7
= 0, x8
= getInt();
610 // non-nested-warning@-1 {{Value stored to 'x8' during its initialization is never read}}
611 // non-nested-warning@-2 {{unused variable 'x8'}}
612 // non-nested-warning@-3 {{unused variable 'x7'}}
614 int x9
= getInt(), x10
= 0;
615 // non-nested-warning@-1 {{Value stored to 'x9' during its initialization is never read}}
616 // non-nested-warning@-2 {{unused variable 'x9'}}
617 // non-nested-warning@-3 {{unused variable 'x10'}}
619 int m
= getInt(), mm
, mmm
;
620 // non-nested-warning@-1 {{Value stored to 'm' during its initialization is never read}}
621 // non-nested-warning@-2 {{unused variable 'm'}}
622 // non-nested-warning@-3 {{unused variable 'mm'}}
623 // non-nested-warning@-4 {{unused variable 'mmm'}}
625 int n
, nn
= getInt();
626 // non-nested-warning@-1 {{Value stored to 'nn' during its initialization is never read}}
627 // non-nested-warning@-2 {{unused variable 'n'}}
628 // non-nested-warning@-3 {{unused variable 'nn'}}
631 p
= (getPtr(), (int *)0); // no warning
634 void testVolatile(void) {
644 struct Foo
rdar34122265_getFoo(void);
646 int rdar34122265_test(int input
) {
647 // This is allowed for defensive programming.
648 struct Foo foo
= {0, 0};
650 foo
= rdar34122265_getFoo();
654 return foo
.x
+ foo
.y
;
657 void rdar34122265_test_cast(void) {
658 // This is allowed for defensive programming.
659 struct Foo foo
= {0, 0};
667 struct Bar
rdar34122265_getBar(void);
669 int rdar34122265_test_nested(int input
) {
670 // This is allowed for defensive programming.
671 struct Bar bar
= {{0, 0}, {0, 0}};
673 bar
= rdar34122265_getBar();
677 return bar
.x
.x
+ bar
.y
.y
;