2017-03-04 02:02:02 +08:00
// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region -fblocks -verify %s
2008-03-31 23:02:58 +08:00
int * f1 ( ) {
int x = 0 ;
2010-06-17 12:21:37 +08:00
return & x ; // expected-warning{{Address of stack memory associated with local variable 'x' returned}} expected-warning{{address of stack memory associated with local variable 'x' returned}}
2008-03-31 23:02:58 +08:00
}
int * f2 ( int y ) {
2018-07-24 05:21:22 +08:00
return & y ; // expected-warning{{Address of stack memory associated with local variable 'y' returned}} expected-warning{{address of stack memory associated with parameter 'y' returned}}
2008-03-31 23:02:58 +08:00
}
int * f3 ( int x , int * y ) {
int w = 0 ;
if ( x )
y = & w ;
2010-06-17 12:21:37 +08:00
return y ; // expected-warning{{Address of stack memory associated with local variable 'w' returned to caller}}
2008-03-31 23:02:58 +08:00
}
2008-10-31 08:19:42 +08:00
void * compound_literal ( int x , int y ) {
2008-10-31 02:46:50 +08:00
if ( x )
2009-05-16 19:45:48 +08:00
return & ( unsigned short ) { ( ( unsigned short ) 0x22EF ) } ; // expected-warning{{Address of stack memory}}
2008-10-31 07:17:05 +08:00
int * array [ ] = { } ;
2008-10-31 02:46:50 +08:00
struct s { int z ; double y ; int w ; } ;
2008-10-31 08:19:42 +08:00
if ( y )
return & ( ( struct s ) { 2 , 0.4 , 5 * 8 } ) ; // expected-warning{{Address of stack memory}}
void * p = & ( ( struct s ) { 42 , 0.4 , x ? 42 : 0 } ) ;
2008-10-31 08:20:13 +08:00
return p ; // expected-warning{{Address of stack memory}}
2008-10-28 05:57:17 +08:00
}
2008-03-31 23:02:58 +08:00
2008-11-02 08:37:31 +08:00
void * alloca_test ( ) {
2009-02-18 09:02:14 +08:00
void * p = __builtin_alloca ( 10 ) ;
2008-11-02 08:37:31 +08:00
return p ; // expected-warning{{Address of stack memory}}
}
2009-07-02 07:24:11 +08:00
int array_test ( int x [ 2 ] ) {
return x [ 0 ] ; // no-warning
}
2009-07-03 06:02:15 +08:00
struct baz {
int x ;
int y [ 2 ] ;
} ;
int struct_test ( struct baz byVal , int flag ) {
if ( flag )
return byVal . x ; // no-warning
else {
return byVal . y [ 0 ] ; // no-warning
}
2009-07-02 07:24:11 +08:00
}
2009-11-26 15:14:50 +08:00
typedef int ( ^ ComparatorBlock ) ( int a , int b ) ;
ComparatorBlock test_return_block ( void ) {
2012-02-19 06:41:01 +08:00
// This block is a global since it has no captures.
2009-11-26 15:14:50 +08:00
ComparatorBlock b = ^ int ( int a , int b ) { return a > b ; } ;
2012-02-19 06:41:01 +08:00
return b ; // no-warning
}
ComparatorBlock test_return_block_with_capture ( int x ) {
// This block is stack allocated because it has captures.
ComparatorBlock b = ^ int ( int a , int b ) { return a > b + x ; } ;
return b ; // expected-warning{{Address of stack-allocated block}}
2009-11-26 15:14:50 +08:00
}
ComparatorBlock test_return_block_neg_aux ( void ) ;
ComparatorBlock test_return_block_neg ( void ) {
ComparatorBlock b = test_return_block_neg_aux ( ) ;
return b ; // no-warning
}
2010-01-10 04:05:00 +08:00
// <rdar://problem/7523821>
int * rdar_7523821_f2 ( ) {
int a [ 3 ] ;
return a ; // expected-warning 2 {{ddress of stack memory associated with local variable 'a' returned}}
} ;
2012-02-19 06:41:01 +08:00
// Handle blocks that have no captures or are otherwise declared 'static'.
// <rdar://problem/10348049>
typedef int ( ^ RDar10348049 ) ( int value ) ;
RDar10348049 test_rdar10348049 ( void ) {
static RDar10348049 b = ^ int ( int x ) {
return x + 2 ;
} ;
return b ; // no-warning
}
2010-01-10 04:05:00 +08:00
2015-02-04 15:15:12 +08:00
void testRegister ( register const char * reg ) {
if ( reg ) ( void ) reg [ 0 ] ;
}
void callTestRegister ( ) {
char buf [ 20 ] ;
testRegister ( buf ) ; // no-warning
}