2012-05-17 00:01:10 +08:00
// RUN: %clang_cc1 -analyze -analyzer-checker=experimental.core.FixedAddr,experimental.core.PointerArithm,experimental.core.PointerSub,debug.ExprInspection -analyzer-store=region -verify -triple x86_64-apple-darwin9 %s
// RUN: %clang_cc1 -analyze -analyzer-checker=experimental.core.FixedAddr,experimental.core.PointerArithm,experimental.core.PointerSub,debug.ExprInspection -analyzer-store=region -verify -triple i686-apple-darwin9 %s
2009-03-03 08:28:42 +08:00
2012-05-17 00:01:10 +08:00
void clang_analyzer_eval ( int ) ;
2010-06-28 16:26:15 +08:00
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
2012-05-17 00:01:10 +08:00
clang_analyzer_eval ( & & start ! = 0 ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( & & start > = 0 ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( & & start > 0 ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( ( & & start - 0 ) ! = 0 ) ; // expected-warning{{TRUE}}
2010-06-28 16:26:15 +08:00
// LHS is a non-symbolic value, RHS is NULL
2012-05-17 00:01:10 +08:00
clang_analyzer_eval ( & a ! = 0 ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( & a > = 0 ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( & a > 0 ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( ( & a - 0 ) ! = 0 ) ; // expected-warning{{TRUE}} expected-warning{{Pointer arithmetic done on non-array variables}}
2010-06-28 16:26:15 +08:00
// LHS is NULL, RHS is non-symbolic
// The same code is used for labels and non-symbolic values.
2012-05-17 00:01:10 +08:00
clang_analyzer_eval ( 0 ! = & a ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( 0 < = & a ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( 0 < & a ) ; // expected-warning{{TRUE}}
2010-06-28 16:26:15 +08:00
// LHS is a symbolic value, RHS is NULL
2012-05-17 00:01:10 +08:00
clang_analyzer_eval ( a ! = 0 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a > = 0 ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( a < = 0 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( ( a - 0 ) ! = 0 ) ; // expected-warning{{UNKNOWN}}
2010-06-28 16:26:15 +08:00
// LHS is NULL, RHS is a symbolic value
2012-05-17 00:01:10 +08:00
clang_analyzer_eval ( 0 ! = a ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( 0 < = a ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( 0 < a ) ; // expected-warning{{UNKNOWN}}
2010-06-28 16:26:15 +08:00
}
void const_locs ( ) {
char * a = ( char * ) 0x1000 ;
char * b = ( char * ) 0x1100 ;
start :
2012-05-17 00:01:10 +08:00
clang_analyzer_eval ( a ! = b ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( a < b ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( a < = b ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( ( b - a ) = = 0x100 ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( & & start = = a ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( a = = & & start ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( & a = = ( char * * ) a ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( ( char * * ) a = = & a ) ; // expected-warning{{UNKNOWN}}
2010-06-28 16:26:15 +08:00
}
void array_matching_types ( ) {
int array [ 10 ] ;
int * a = & array [ 2 ] ;
int * b = & array [ 5 ] ;
2012-05-17 00:01:10 +08:00
clang_analyzer_eval ( a ! = b ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( a < b ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( a < = b ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( ( b - a ) ! = 0 ) ; // expected-warning{{TRUE}}
2010-06-28 16:26:15 +08:00
}
// 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 ] ;
2012-05-17 00:01:10 +08:00
clang_analyzer_eval ( a ! = b ) ; // expected-warning{{TRUE}} expected-warning{{comparison of distinct pointer types}}
clang_analyzer_eval ( a < b ) ; // expected-warning{{TRUE}} expected-warning{{comparison of distinct pointer types}}
clang_analyzer_eval ( a < = b ) ; // expected-warning{{TRUE}} expected-warning{{comparison of distinct pointer types}}
2010-06-28 16:26:15 +08:00
}
struct test { int x ; int y ; } ;
void struct_fields ( ) {
struct test a , b ;
2012-05-17 00:01:10 +08:00
clang_analyzer_eval ( & a . x ! = & a . y ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( & a . x < & a . y ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( & a . x < = & a . y ) ; // expected-warning{{TRUE}}
2010-06-28 16:26:15 +08:00
2012-05-17 00:01:10 +08:00
clang_analyzer_eval ( & a . x ! = & b . x ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( & a . x > & b . x ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( & a . x > = & b . x ) ; // expected-warning{{UNKNOWN}}
2010-06-28 16:26:15 +08:00
}
void mixed_region_types ( ) {
struct test s ;
int array [ 2 ] ;
void * a = & array , * b = & s ;
2012-05-17 00:01:10 +08:00
clang_analyzer_eval ( & a ! = & b ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( & a > & b ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( & a > = & b ) ; // expected-warning{{UNKNOWN}}
2010-06-28 16:26:15 +08:00
}
void symbolic_region ( int * p ) {
int a ;
2012-05-17 00:01:10 +08:00
clang_analyzer_eval ( & a ! = p ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( & a > p ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( & a > = p ) ; // expected-warning{{UNKNOWN}}
2010-06-28 16:26:15 +08:00
}
2010-06-30 09:35:20 +08:00
void PR7527 ( int * p ) {
if ( ( ( int ) p ) & 1 ) // not crash
return ;
}