2011-03-12 14:14:28 +08:00
// RUN: %clang_cc1 -Wunused-variable -analyze -analyzer-checker=core,deadcode.DeadStores,deadcode.IdempotentOperations -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
// RUN: %clang_cc1 -Wunused-variable -analyze -analyzer-checker=core,deadcode.DeadStores,deadcode.IdempotentOperations -analyzer-store=region -analyzer-constraints=basic -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
// RUN: %clang_cc1 -Wunused-variable -analyze -analyzer-checker=core,deadcode.DeadStores,deadcode.IdempotentOperations -analyzer-store=region -analyzer-constraints=range -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
2007-11-19 14:38:23 +08:00
2008-04-14 23:56:17 +08:00
void f1 ( ) {
2010-03-18 09:22:39 +08:00
int k , y ; // expected-warning{{unused variable 'k'}} expected-warning{{unused variable 'y'}}
2008-03-19 15:31:52 +08:00
int abc = 1 ;
2010-03-18 09:22:39 +08:00
long idx = abc + 3 * 5 ; // expected-warning {{never read}} expected-warning{{unused variable 'idx'}}
2007-11-19 04:06:35 +08:00
}
2007-11-19 14:38:23 +08:00
2008-04-14 23:56:17 +08:00
void f2 ( void * b ) {
2007-11-19 14:38:23 +08:00
char * c = ( char * ) b ; // no-warning
2010-03-18 09:22:39 +08:00
char * d = b + 1 ; // expected-warning {{never read}} expected-warning{{unused variable 'd'}}
2010-09-05 08:04:01 +08:00
printf ( " %s " , c ) ; / / expected - warning { { implicitly declaring C library function ' printf ' with type ' int ( const char * , . . . ) ' } } \
2009-02-14 08:32:47 +08:00
// expected-note{{please include the header <stdio.h> or explicitly provide a declaration for 'printf'}}
2007-11-19 14:38:23 +08:00
}
2007-11-20 11:03:00 +08:00
2010-01-10 04:43:19 +08:00
int f ( ) ;
2008-04-14 23:56:17 +08:00
void f3 ( ) {
2008-03-19 15:31:52 +08:00
int r ;
if ( ( r = f ( ) ) ! = 0 ) { // no-warning
int y = r ; // no-warning
printf ( " the error is: %d \n " , y ) ;
}
2007-11-20 11:03:00 +08:00
}
2008-04-14 23:56:17 +08:00
void f4 ( int k ) {
k = 1 ;
if ( k )
f1 ( ) ;
2008-06-21 05:45:25 +08:00
k = 2 ; // expected-warning {{never read}}
2008-04-14 23:56:17 +08:00
}
2009-11-23 04:26:21 +08:00
2008-04-16 02:37:29 +08:00
void f5 ( ) {
int x = 4 ; // no-warning
2010-03-18 09:22:39 +08:00
int * p = & x ; // expected-warning{{never read}} expected-warning{{unused variable 'p'}}
2008-04-16 02:37:29 +08:00
2008-05-06 07:12:21 +08:00
}
2011-02-12 08:17:19 +08:00
//
2008-05-06 07:12:21 +08:00
int f6 ( ) {
int x = 4 ;
2011-02-12 08:17:19 +08:00
+ + x ; // no-warning
2008-05-06 07:12:21 +08:00
return 1 ;
}
2008-06-21 05:45:25 +08:00
int f7 ( int * p ) {
// This is allowed for defensive programming.
p = 0 ; // no-warning
return 1 ;
}
2009-11-23 04:26:21 +08:00
int f7b ( int * p ) {
// This is allowed for defensive programming.
p = ( 0 ) ; // no-warning
return 1 ;
}
int f7c ( int * p ) {
// This is allowed for defensive programming.
p = ( void * ) 0 ; // no-warning
return 1 ;
}
int f7d ( int * p ) {
// This is allowed for defensive programming.
p = ( void * ) ( 0 ) ; // no-warning
return 1 ;
}
2011-01-14 04:58:56 +08:00
// Don't warn for dead stores in nested expressions. We have yet
// to see a real bug in this scenario.
2008-06-21 05:45:25 +08:00
int f8 ( int * p ) {
2008-08-05 08:07:51 +08:00
extern int * baz ( ) ;
2011-01-14 04:58:56 +08:00
if ( ( p = baz ( ) ) ) // no-warning
2008-06-21 05:45:25 +08:00
return 1 ;
return 0 ;
}
2008-07-24 05:16:38 +08:00
int f9 ( ) {
int x = 4 ;
x = x + 10 ; // expected-warning{{never read}}
return 1 ;
}
int f10 ( ) {
int x = 4 ;
x = 10 + x ; // expected-warning{{never read}}
return 1 ;
}
2008-07-24 07:18:43 +08:00
int f11 ( ) {
int x = 4 ;
2008-10-15 13:23:41 +08:00
return x + + ; // expected-warning{{never read}}
2008-07-24 07:18:43 +08:00
}
2008-10-15 13:23:41 +08:00
int f11b ( ) {
int x = 4 ;
2009-01-20 08:47:45 +08:00
return ( ( ( ( + + x ) ) ) ) ; // no-warning
2008-10-15 13:23:41 +08:00
}
2008-07-25 12:47:34 +08:00
int f12a ( int y ) {
2010-03-18 09:22:39 +08:00
int x = y ; // expected-warning{{unused variable 'x'}}
2008-07-25 12:47:34 +08:00
return 1 ;
}
int f12b ( int y ) {
int x __attribute__ ( ( unused ) ) = y ; // no-warning
return 1 ;
}
2010-03-18 09:22:39 +08:00
int f12c ( int y ) {
// Allow initialiation of scalar variables by parameters as a form of
// defensive programming.
int x = y ; // no-warning
x = 1 ;
return x ;
}
2008-07-24 05:16:38 +08:00
2008-08-07 07:26:31 +08:00
// Filed with PR 2630. This code should produce no warnings.
int f13 ( void )
{
int a = 1 ;
int b , c = b = a + a ;
if ( b > 0 )
return ( 0 ) ;
return ( a + b + c ) ;
}
2008-09-05 05:52:52 +08:00
// Filed with PR 2763.
2008-09-26 13:52:45 +08:00
int f14 ( int count ) {
2008-09-05 05:52:52 +08:00
int index , nextLineIndex ;
for ( index = 0 ; index < count ; index = nextLineIndex + 1 ) {
nextLineIndex = index + 1 ; // no-warning
continue ;
}
return index ;
}
2008-09-26 13:52:45 +08:00
// Test case for <rdar://problem/6248086>
void f15 ( unsigned x , unsigned y ) {
int count = x * y ; // no-warning
2010-03-18 09:22:39 +08:00
int z [ count ] ; // expected-warning{{unused variable 'z'}}
2008-09-26 13:52:45 +08:00
}
2011-01-14 04:58:56 +08:00
// Don't warn for dead stores in nested expressions. We have yet
// to see a real bug in this scenario.
2008-09-27 06:58:57 +08:00
int f16 ( int x ) {
x = x * 2 ;
2011-01-14 04:58:56 +08:00
x = sizeof ( int [ x = ( x | | x + 1 ) * 2 ] ) // expected-warning{{The left operand to '+' is always 0}} expected-warning{{The left operand to '*' is always 1}}
2008-09-27 07:05:47 +08:00
? 5 : 8 ;
2008-09-27 06:58:57 +08:00
return x ;
}
2009-01-10 06:15:01 +08:00
// Self-assignments should not be flagged as dead stores.
2009-07-22 03:01:31 +08:00
void f17 ( ) {
2009-01-10 06:15:01 +08:00
int x = 1 ;
2010-08-25 05:09:07 +08:00
x = x ;
2009-01-10 06:15:01 +08:00
}
2009-01-20 08:47:45 +08:00
// <rdar://problem/6506065>
// The values of dead stores are only "consumed" in an enclosing expression
2009-07-17 09:04:31 +08:00
// what that value is actually used. In other words, don't say "Although the
// value stored to 'x' is used...".
2009-01-20 08:47:45 +08:00
int f18 ( ) {
int x = 0 ; // no-warning
if ( 1 )
x = 10 ; // expected-warning{{Value stored to 'x' is never read}}
while ( 1 )
x = 10 ; // expected-warning{{Value stored to 'x' is never read}}
2011-02-12 07:24:26 +08:00
// unreachable.
2009-01-20 08:47:45 +08:00
do
2011-02-12 07:24:26 +08:00
x = 10 ; // no-warning
2009-01-20 08:47:45 +08:00
while ( 1 ) ;
2011-02-12 07:24:26 +08:00
return ( x = 10 ) ; // no-warning
}
2009-01-20 08:47:45 +08:00
2011-02-12 07:24:26 +08:00
int f18_a ( ) {
int x = 0 ; // no-warning
2011-01-14 04:58:56 +08:00
return ( x = 10 ) ; // no-warning
2009-01-20 08:47:45 +08:00
}
2009-02-10 02:01:00 +08:00
2011-02-12 07:24:26 +08:00
void f18_b ( ) {
int x = 0 ; // no-warning
if ( 1 )
x = 10 ; // expected-warning{{Value stored to 'x' is never read}}
}
void f18_c ( ) {
int x = 0 ;
while ( 1 )
x = 10 ; // expected-warning{{Value stored to 'x' is never read}}
}
void f18_d ( ) {
int x = 0 ; // no-warning
do
x = 10 ; // expected-warning{{Value stored to 'x' is never read}}
while ( 1 ) ;
}
2009-02-10 02:01:00 +08:00
// PR 3514: false positive `dead initialization` warning for init to global
// http://llvm.org/bugs/show_bug.cgi?id=3514
extern const int MyConstant ;
int f19 ( void ) {
int x = MyConstant ; // no-warning
x = 1 ;
return x ;
}
2009-03-31 11:34:38 +08:00
int f19b ( void ) { // This case is the same as f19.
2009-02-10 02:01:00 +08:00
const int MyConstant = 0 ;
2009-03-31 11:34:38 +08:00
int x = MyConstant ; // no-warning
2009-02-10 02:01:00 +08:00
x = 1 ;
return x ;
}
2009-03-24 06:30:58 +08:00
void f20 ( void ) {
int x = 1 ; // no-warning
# pragma unused(x)
}
2009-07-17 09:04:31 +08:00
void halt ( ) __attribute__ ( ( noreturn ) ) ;
int f21 ( ) {
int x = 4 ;
2011-02-12 08:17:19 +08:00
x = x + 1 ; // expected-warning{{never read}}
2009-07-17 09:04:31 +08:00
if ( 1 ) {
halt ( ) ;
( void ) x ;
}
return 1 ;
}
2009-07-21 07:24:15 +08:00
int j ;
void f22 ( ) {
int x = 4 ;
int y1 = 4 ;
int y2 = 4 ;
int y3 = 4 ;
int y4 = 4 ;
int y5 = 4 ;
int y6 = 4 ;
int y7 = 4 ;
int y8 = 4 ;
int y9 = 4 ;
int y10 = 4 ;
2009-07-21 08:38:52 +08:00
int y11 = 4 ;
int y12 = 4 ;
2009-07-21 09:12:51 +08:00
int y13 = 4 ;
int y14 = 4 ;
int y15 = 4 ;
2009-07-21 09:27:50 +08:00
int y16 = 4 ;
int y17 = 4 ;
int y18 = 4 ;
2009-07-21 09:46:17 +08:00
int y19 = 4 ;
int y20 = 4 ;
2009-07-21 07:24:15 +08:00
2011-02-12 08:17:19 +08:00
x = x + 1 ; // expected-warning{{never read}}
2009-07-21 07:24:15 +08:00
+ + y1 ;
+ + y2 ;
+ + y3 ;
+ + y4 ;
+ + y5 ;
+ + y6 ;
+ + y7 ;
+ + y8 ;
+ + y9 ;
+ + y10 ;
2009-07-21 08:38:52 +08:00
+ + y11 ;
+ + y12 ;
2009-07-21 09:12:51 +08:00
+ + y13 ;
+ + y14 ;
+ + y15 ;
2009-07-21 09:27:50 +08:00
+ + y16 ;
+ + y17 ;
+ + y18 ;
2009-07-21 09:46:17 +08:00
+ + y19 ;
+ + y20 ;
2009-07-21 07:24:15 +08:00
switch ( j ) {
case 1 :
if ( 0 )
( void ) x ;
if ( 1 ) {
( void ) y1 ;
return ;
}
( void ) x ;
break ;
case 2 :
if ( 0 )
( void ) x ;
else {
( void ) y2 ;
return ;
}
( void ) x ;
break ;
case 3 :
if ( 1 ) {
( void ) y3 ;
return ;
} else
( void ) x ;
( void ) x ;
break ;
case 4 :
0 ? : ( ( void ) y4 , ( { return ; } ) ) ;
( void ) x ;
break ;
case 5 :
1 ? : ( void ) x ;
0 ? ( void ) x : ( ( void ) y5 , ( { return ; } ) ) ;
( void ) x ;
break ;
case 6 :
1 ? ( ( void ) y6 , ( { return ; } ) ) : ( void ) x ;
( void ) x ;
break ;
case 7 :
( void ) ( 0 & & x ) ;
( void ) y7 ;
2010-09-20 07:03:35 +08:00
( void ) ( 0 | | ( y8 , ( { return ; } ) , 1 ) ) ; // expected-warning {{expression result unused}}
2009-07-21 07:24:15 +08:00
( void ) x ;
break ;
case 8 :
2010-09-20 07:03:35 +08:00
( void ) ( 1 & & ( y9 , ( { return ; } ) , 1 ) ) ; // expected-warning {{expression result unused}}
2009-07-21 07:24:15 +08:00
( void ) x ;
break ;
case 9 :
( void ) ( 1 | | x ) ;
( void ) y10 ;
2009-07-21 08:38:52 +08:00
break ;
case 10 :
2009-07-21 09:27:50 +08:00
while ( 0 ) {
( void ) x ;
2009-07-21 08:38:52 +08:00
}
2009-07-21 09:27:50 +08:00
( void ) y11 ;
2009-07-21 08:38:52 +08:00
break ;
case 11 :
2009-07-21 09:27:50 +08:00
while ( 1 ) {
( void ) y12 ;
2009-07-21 08:38:52 +08:00
}
2009-07-21 09:27:50 +08:00
( void ) x ;
2009-07-21 08:38:52 +08:00
break ;
2009-07-21 09:12:51 +08:00
case 12 :
2009-07-21 09:27:50 +08:00
do {
2009-07-21 09:12:51 +08:00
( void ) y13 ;
2009-07-21 09:27:50 +08:00
} while ( 0 ) ;
( void ) y14 ;
break ;
case 13 :
do {
( void ) y15 ;
} while ( 1 ) ;
( void ) x ;
break ;
case 14 :
for ( ; ; ) {
( void ) y16 ;
2009-07-21 09:12:51 +08:00
}
( void ) x ;
break ;
2009-07-21 09:27:50 +08:00
case 15 :
2009-07-21 09:12:51 +08:00
for ( ; 1 ; ) {
2009-07-21 09:27:50 +08:00
( void ) y17 ;
2009-07-21 09:12:51 +08:00
}
( void ) x ;
break ;
2009-07-21 09:27:50 +08:00
case 16 :
2009-07-21 09:12:51 +08:00
for ( ; 0 ; ) {
( void ) x ;
}
2009-07-21 09:27:50 +08:00
( void ) y18 ;
2009-07-21 09:12:51 +08:00
break ;
2009-07-21 09:46:17 +08:00
case 17 :
__builtin_choose_expr ( 0 , ( void ) x , ( ( void ) y19 , ( { return ; } ) ) ) ;
( void ) x ;
break ;
case 19 :
__builtin_choose_expr ( 1 , ( ( void ) y20 , ( { return ; } ) ) , ( void ) x ) ;
( void ) x ;
break ;
2009-07-21 07:24:15 +08:00
}
}
2009-11-26 14:55:36 +08:00
void f23_aux ( const char * s ) ;
void f23 ( int argc , char * * argv ) {
int shouldLog = ( argc > 1 ) ; // no-warning
^ {
if ( shouldLog ) f23_aux ( " I did too use it! \n " ) ;
else f23_aux ( " I shouldn't log. Wait.. d'oh! \n " ) ;
} ( ) ;
}
void f23_pos ( int argc , char * * argv ) {
2010-03-18 09:22:39 +08:00
int shouldLog = ( argc > 1 ) ; // expected-warning{{Value stored to 'shouldLog' during its initialization is never read}} expected-warning{{unused variable 'shouldLog'}}
2009-11-26 14:55:36 +08:00
^ {
f23_aux ( " I did too use it! \n " ) ;
} ( ) ;
}
2009-12-02 07:04:14 +08:00
void f24_A ( int y ) {
// FIXME: One day this should be reported as dead since 'z = x + y' is dead.
int x = ( y > 2 ) ; // no-warning
^ {
2010-03-18 09:22:39 +08:00
int z = x + y ; // expected-warning{{Value stored to 'z' during its initialization is never read}} expected-warning{{unused variable 'z'}}
2009-12-02 07:04:14 +08:00
} ( ) ;
}
void f24_B ( int y ) {
// FIXME: One day this should be reported as dead since 'x' is just overwritten.
__block int x = ( y > 2 ) ; // no-warning
^ {
// FIXME: This should eventually be a dead store since it is never read either.
x = 5 ; // no-warning
} ( ) ;
}
int f24_C ( int y ) {
// FIXME: One day this should be reported as dead since 'x' is just overwritten.
__block int x = ( y > 2 ) ; // no-warning
^ {
x = 5 ; // no-warning
} ( ) ;
return x ;
}
int f24_D ( int y ) {
__block int x = ( y > 2 ) ; // no-warning
^ {
if ( y > 4 )
x = 5 ; // no-warning
} ( ) ;
return x ;
}
2009-12-03 08:46:16 +08:00
// This example shows that writing to a variable captured by a block means that it might
// not be dead.
int f25 ( int y ) {
__block int x = ( y > 2 ) ;
__block int z = 0 ;
void ( ^ foo ) ( ) = ^ { z = x + y ; } ;
x = 4 ; // no-warning
foo ( ) ;
return z ;
}
// This test is mostly the same as 'f25', but shows that the heuristic of pruning out dead
// stores for variables that are just marked '__block' is overly conservative.
int f25_b ( int y ) {
// FIXME: we should eventually report a dead store here.
__block int x = ( y > 2 ) ;
__block int z = 0 ;
x = 4 ; // no-warning
return z ;
}
2010-03-10 08:18:11 +08:00
int f26_nestedblocks ( ) {
int z ;
z = 1 ;
__block int y = 0 ;
^ {
int k ;
k = 1 ; // expected-warning{{Value stored to 'k' is never read}}
^ {
y = z + 1 ;
} ( ) ;
} ( ) ;
return y ;
}
2010-05-22 04:30:15 +08:00
// The FOREACH macro in QT uses 'break' statements within statement expressions
// placed within the increment code of for loops.
void rdar8014335 ( ) {
for ( int i = 0 ; i ! = 10 ; ( { break ; } ) ) {
for ( ; ; ( { + + i ; break ; } ) ) ;
// Note that the next value stored to 'i' is never executed
// because the next statement to be executed is the 'break'
// in the increment code of the first loop.
2010-07-28 02:49:08 +08:00
i = i * 3 ; // expected-warning{{Value stored to 'i' is never read}} expected-warning{{The left operand to '*' is always 1}}
2010-05-22 04:30:15 +08:00
}
}
2010-08-18 05:00:06 +08:00
// <rdar://problem/8320674> NullStmts followed by do...while() can lead to disconnected CFG
//
// This previously caused bogus dead-stores warnings because the body of the first do...while was
// disconnected from the entry of the function.
typedef struct { float r ; float i ; } s_rdar8320674 ;
typedef struct { s_rdar8320674 x [ 1 ] ; } s2_rdar8320674 ;
void rdar8320674 ( s_rdar8320674 * z , unsigned y , s2_rdar8320674 * st , int m )
{
s_rdar8320674 * z2 ;
s_rdar8320674 * tw1 = st - > x ;
s_rdar8320674 t ;
z2 = z + m ;
do {
; ;
do { ( t ) . r = ( * z2 ) . r * ( * tw1 ) . r - ( * z2 ) . i * ( * tw1 ) . i ; ( t ) . i = ( * z2 ) . r * ( * tw1 ) . i + ( * z2 ) . i * ( * tw1 ) . r ; } while ( 0 ) ;
tw1 + = y ;
do { ( * z2 ) . r = ( * z ) . r - ( t ) . r ; ( * z2 ) . i = ( * z ) . i - ( t ) . i ; } while ( 0 ) ;
do { ( * z ) . r + = ( t ) . r ; ( * z ) . i + = ( t ) . i ; } while ( 0 ) ;
+ + z2 ;
+ + z ;
} while ( - - m ) ;
}
2011-02-12 07:24:26 +08:00
// Avoid dead stores resulting from an assignment (and use) being unreachable.
void rdar8405222_aux ( int i ) ;
void rdar8405222 ( ) {
const int show = 0 ;
int i = 0 ;
if ( show )
i = 5 ; // no-warning
if ( show )
rdar8405222_aux ( i ) ;
}