2011-02-16 06:55:20 +08:00
// RUN: %clang_cc1 -analyze -analyzer-checker=core.experimental.FixedAddr -analyzer-checker=core.experimental.PointerArithm -analyzer-checker=core.experimental.PointerSub -analyzer-check-objc-mem -analyzer-store=region -verify -triple x86_64-apple-darwin9 %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core.experimental.FixedAddr -analyzer-checker=core.experimental.PointerArithm -analyzer-checker=core.experimental.PointerSub -analyzer-check-objc-mem -analyzer-store=region -verify -triple i686-apple-darwin9 %s
2009-03-03 08:28:42 +08:00
2010-06-28 16:26:15 +08:00
// Used to trigger warnings for unreachable paths.
# define WARN do { int a, b; int c = &b-&a; } while (0)
2009-03-03 08:28:42 +08:00
void f1 ( ) {
int a [ 10 ] ;
int * p = a ;
+ + p ;
}
2009-03-11 15:43:49 +08:00
char * foo ( ) ;
void f2 ( ) {
char * p = foo ( ) ;
+ + p ;
}
2009-03-11 17:15:38 +08:00
2009-03-12 09:55:38 +08:00
// This test case checks if we get the right rvalue type of a TypedViewRegion.
// The ElementRegion's type depends on the array region's rvalue type. If it was
// a pointer type, we would get a loc::SymbolVal for '*p'.
2009-06-05 03:35:30 +08:00
void * memchr ( ) ;
2009-03-11 17:15:38 +08:00
static int
domain_port ( const char * domain_b , const char * domain_e ,
const char * * domain_e_ptr )
{
int port = 0 ;
const char * p ;
const char * colon = memchr ( domain_b , ' : ' , domain_e - domain_b ) ;
for ( p = colon + 1 ; p < domain_e ; p + + )
port = 10 * port + ( * p - ' 0 ' ) ;
return port ;
}
2009-11-09 13:34:10 +08:00
void f3 ( ) {
int x , y ;
int d = & y - & x ; // expected-warning{{Subtraction of two pointers that do not point to the same memory chunk may cause incorrect result.}}
2009-11-10 10:37:53 +08:00
int a [ 10 ] ;
int * p = & a [ 2 ] ;
int * q = & a [ 8 ] ;
d = q - p ; // no-warning
2009-11-09 13:34:10 +08:00
}
2009-11-09 14:52:44 +08:00
void f4 ( ) {
int * p ;
p = ( int * ) 0x10000 ; // expected-warning{{Using a fixed address is not portable because that address will probably not be valid in all environments or platforms.}}
}
2009-11-09 21:23:31 +08:00
void f5 ( ) {
int x , y ;
int * p ;
2009-11-09 21:56:44 +08:00
p = & x + 1 ; // expected-warning{{Pointer arithmetic done on non-array variables means reliance on memory layout, which is dangerous.}}
2009-11-09 21:23:31 +08:00
int a [ 10 ] ;
p = a + 1 ; // no-warning
}
2009-11-10 10:45:49 +08:00
// Allow arithmetic on different symbolic regions.
void f6 ( int * p , int * q ) {
int d = q - p ; // no-warning
}
2010-06-28 16:26:15 +08:00
void null_operand ( int * a ) {
start :
// LHS is a label, RHS is NULL
if ( & & start = = 0 )
WARN ; // no-warning
if ( & & start < 0 )
WARN ; // no-warning
if ( & & start < = 0 )
WARN ; // no-warning
if ( ! ( & & start ! = 0 ) )
WARN ; // no-warning
if ( ! ( & & start > 0 ) )
WARN ; // no-warning
if ( ! ( & & start > = 0 ) )
WARN ; // no-warning
if ( ! ( & & start - 0 ) )
WARN ; // no-warning
// LHS is a non-symbolic value, RHS is NULL
if ( & a = = 0 )
WARN ; // no-warning
if ( & a < 0 )
WARN ; // no-warning
if ( & a < = 0 )
WARN ; // no-warning
if ( ! ( & a ! = 0 ) )
WARN ; // no-warning
if ( ! ( & a > 0 ) )
WARN ; // no-warning
if ( ! ( & a > = 0 ) )
WARN ; // no-warning
if ( ! ( & a - 0 ) ) // expected-warning{{Pointer arithmetic done on non-array variables}}
WARN ; // no-warning
// LHS is NULL, RHS is non-symbolic
// The same code is used for labels and non-symbolic values.
if ( 0 = = & a )
WARN ; // no-warning
if ( 0 > & a )
WARN ; // no-warning
if ( 0 > = & a )
WARN ; // no-warning
if ( ! ( 0 ! = & a ) )
WARN ; // no-warning
if ( ! ( 0 < & a ) )
WARN ; // no-warning
if ( ! ( 0 < = & a ) )
WARN ; // no-warning
// LHS is a symbolic value, RHS is NULL
if ( a = = 0 )
WARN ; // expected-warning{{}}
if ( a < 0 )
WARN ; // no-warning
if ( a < = 0 )
WARN ; // expected-warning{{}}
if ( ! ( a ! = 0 ) )
WARN ; // expected-warning{{}}
if ( ! ( a > 0 ) )
WARN ; // expected-warning{{}}
if ( ! ( a > = 0 ) )
WARN ; // no-warning
if ( ! ( a - 0 ) )
WARN ; // expected-warning{{}}
// LHS is NULL, RHS is a symbolic value
if ( 0 = = a )
WARN ; // expected-warning{{}}
if ( 0 > a )
WARN ; // no-warning
if ( 0 > = a )
WARN ; // expected-warning{{}}
if ( ! ( 0 ! = a ) )
WARN ; // expected-warning{{}}
if ( ! ( 0 < a ) )
WARN ; // expected-warning{{}}
if ( ! ( 0 < = a ) )
WARN ; // no-warning
}
void const_locs ( ) {
char * a = ( char * ) 0x1000 ;
char * b = ( char * ) 0x1100 ;
start :
if ( a = = b )
WARN ; // no-warning
if ( ! ( a ! = b ) )
WARN ; // no-warning
if ( a > b )
WARN ; // no-warning
if ( b < a )
WARN ; // no-warning
if ( a > = b )
WARN ; // no-warning
if ( b < = a )
WARN ; // no-warning
if ( b - a ! = 0x100 )
WARN ; // no-warning
if ( & & start = = a )
WARN ; // expected-warning{{}}
if ( a = = & & start )
WARN ; // expected-warning{{}}
if ( & a = = ( char * * ) a )
WARN ; // expected-warning{{}}
if ( ( char * * ) a = = & a )
WARN ; // expected-warning{{}}
}
void array_matching_types ( ) {
int array [ 10 ] ;
int * a = & array [ 2 ] ;
int * b = & array [ 5 ] ;
if ( a = = b )
WARN ; // no-warning
if ( ! ( a ! = b ) )
WARN ; // no-warning
if ( a > b )
WARN ; // no-warning
if ( b < a )
WARN ; // no-warning
if ( a > = b )
WARN ; // no-warning
if ( b < = a )
WARN ; // no-warning
if ( ( b - a ) = = 0 )
WARN ; // no-warning
}
// This takes a different code path than array_matching_types()
void array_different_types ( ) {
int array [ 10 ] ;
int * a = & array [ 2 ] ;
char * b = ( char * ) & array [ 5 ] ;
if ( a = = b ) // expected-warning{{comparison of distinct pointer types}}
WARN ; // no-warning
if ( ! ( a ! = b ) ) // expected-warning{{comparison of distinct pointer types}}
WARN ; // no-warning
if ( a > b ) // expected-warning{{comparison of distinct pointer types}}
WARN ; // no-warning
if ( b < a ) // expected-warning{{comparison of distinct pointer types}}
WARN ; // no-warning
if ( a > = b ) // expected-warning{{comparison of distinct pointer types}}
WARN ; // no-warning
if ( b < = a ) // expected-warning{{comparison of distinct pointer types}}
WARN ; // no-warning
}
struct test { int x ; int y ; } ;
void struct_fields ( ) {
struct test a , b ;
if ( & a . x = = & a . y )
WARN ; // no-warning
if ( ! ( & a . x ! = & a . y ) )
WARN ; // no-warning
if ( & a . x > & a . y )
WARN ; // no-warning
if ( & a . y < & a . x )
WARN ; // no-warning
if ( & a . x > = & a . y )
WARN ; // no-warning
if ( & a . y < = & a . x )
WARN ; // no-warning
if ( & a . x = = & b . x )
WARN ; // no-warning
if ( ! ( & a . x ! = & b . x ) )
WARN ; // no-warning
if ( & a . x > & b . x )
WARN ; // expected-warning{{}}
if ( & b . x < & a . x )
WARN ; // expected-warning{{}}
if ( & a . x > = & b . x )
WARN ; // expected-warning{{}}
if ( & b . x < = & a . x )
WARN ; // expected-warning{{}}
}
void mixed_region_types ( ) {
struct test s ;
int array [ 2 ] ;
void * a = & array , * b = & s ;
if ( & a = = & b )
WARN ; // no-warning
if ( ! ( & a ! = & b ) )
WARN ; // no-warning
if ( & a > & b )
WARN ; // expected-warning{{}}
if ( & b < & a )
WARN ; // expected-warning{{}}
if ( & a > = & b )
WARN ; // expected-warning{{}}
if ( & b < = & a )
WARN ; // expected-warning{{}}
}
void symbolic_region ( int * p ) {
int a ;
if ( & a = = p )
WARN ; // expected-warning{{}}
if ( & a ! = p )
WARN ; // expected-warning{{}}
if ( & a > p )
WARN ; // expected-warning{{}}
if ( & a < p )
WARN ; // expected-warning{{}}
if ( & a > = p )
WARN ; // expected-warning{{}}
if ( & a < = p )
WARN ; // expected-warning{{}}
}
2010-06-30 09:35:20 +08:00
void PR7527 ( int * p ) {
if ( ( ( int ) p ) & 1 ) // not crash
return ;
}