2017-03-04 02:02:02 +08:00
// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin9 -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify %s
// RUN: %clang_analyze_cc1 -triple i386-apple-darwin9 -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify %s
2013-05-02 02:19:59 +08:00
extern void clang_analyzer_eval ( _Bool ) ;
2009-04-28 21:52:13 +08:00
2009-04-29 13:59:48 +08:00
// Test if the 'storage' region gets properly initialized after it is cast to
// 'struct sockaddr *'.
2009-08-20 12:48:23 +08:00
typedef unsigned char __uint8_t ;
typedef unsigned int __uint32_t ;
typedef __uint32_t __darwin_socklen_t ;
typedef __uint8_t sa_family_t ;
typedef __darwin_socklen_t socklen_t ;
struct sockaddr { sa_family_t sa_family ; } ;
struct sockaddr_storage { } ;
2009-07-11 04:10:06 +08:00
2010-01-10 04:43:19 +08:00
void getsockname ( ) ;
2009-04-28 21:52:13 +08:00
void f ( int sock ) {
struct sockaddr_storage storage ;
2016-09-26 23:17:18 +08:00
struct sockaddr * sockaddr = ( struct sockaddr * ) & storage ; // expected-warning{{Casting data to a larger structure type and accessing a field can lead to memory access errors or data corruption}}
2009-04-28 21:52:13 +08:00
socklen_t addrlen = sizeof ( storage ) ;
getsockname ( sock , sockaddr , & addrlen ) ;
switch ( sockaddr - > sa_family ) { // no-warning
default :
;
}
}
2009-06-18 14:29:10 +08:00
struct s {
struct s * value ;
} ;
2009-07-22 02:45:53 +08:00
void f1 ( struct s * * pval ) {
2009-06-18 14:29:10 +08:00
int * tbool = ( ( void * ) 0 ) ;
struct s * t = * pval ;
pval = & ( t - > value ) ;
2009-10-14 14:05:09 +08:00
tbool = ( int * ) pval ; // use the cast-to type 'int *' to create element region.
2009-06-18 14:49:35 +08:00
char c = ( unsigned char ) * tbool ; // Should use cast-to type to create symbol.
2009-10-14 14:05:09 +08:00
if ( * tbool = = - 1 ) // here load the element region with the correct type 'int'
2009-07-31 06:37:41 +08:00
( void ) 3 ;
2009-06-18 14:29:10 +08:00
}
2009-06-19 12:51:14 +08:00
void f2 ( const char * str ) {
unsigned char ch , cl , * p ;
p = ( unsigned char * ) str ;
ch = * p + + ; // use cast-to type 'unsigned char' to create element region.
cl = * p + + ;
if ( ! cl )
cl = ' a ' ;
}
2010-01-05 19:49:21 +08:00
// Test cast VariableSizeArray to pointer does not crash.
void * memcpy ( void * , void const * , unsigned long ) ;
typedef unsigned char Byte ;
void doit ( char * data , int len ) {
if ( len ) {
Byte buf [ len ] ;
memcpy ( buf , data , len ) ;
}
}
2010-01-14 11:45:06 +08:00
2010-01-15 03:47:50 +08:00
// PR 6013 and 6035 - Test that a cast of a pointer to long and then to int does not crash SValuator.
void pr6013_6035_test ( void * p ) {
unsigned int foo ;
foo = ( ( long ) ( p ) ) ;
( void ) foo ;
2010-01-14 11:45:06 +08:00
}
2012-05-11 05:49:52 +08:00
// PR12511 and radar://11215362 - Test that we support SymCastExpr, which represents symbolic int to float cast.
char ttt ( int intSeconds ) {
double seconds = intSeconds ;
if ( seconds )
return 0 ;
return 0 ;
}
2013-02-06 03:52:28 +08:00
int foo ( int * p ) {
int y = 0 ;
if ( p = = 0 ) {
if ( ( * ( ( void * * ) & p ) ) = = ( void * ) 0 ) // Test that the cast to void preserves the symbolic region.
return 0 ;
else
return 5 / y ; // This code should be unreachable: no-warning.
}
return 0 ;
}
2013-05-02 02:19:59 +08:00
void castsToBool ( ) {
clang_analyzer_eval ( 0 ) ; // expected-warning{{FALSE}}
clang_analyzer_eval ( 0U ) ; // expected-warning{{FALSE}}
clang_analyzer_eval ( ( void * ) 0 ) ; // expected-warning{{FALSE}}
clang_analyzer_eval ( 1 ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( 1U ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( - 1 ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( 0x100 ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( 0x100U ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( ( void * ) 0x100 ) ; // expected-warning{{TRUE}}
extern int symbolicInt ;
clang_analyzer_eval ( symbolicInt ) ; // expected-warning{{UNKNOWN}}
if ( symbolicInt )
clang_analyzer_eval ( symbolicInt ) ; // expected-warning{{TRUE}}
extern void * symbolicPointer ;
clang_analyzer_eval ( symbolicPointer ) ; // expected-warning{{UNKNOWN}}
if ( symbolicPointer )
clang_analyzer_eval ( symbolicPointer ) ; // expected-warning{{TRUE}}
int localInt ;
2014-02-26 10:36:06 +08:00
int * ptr = & localInt ;
clang_analyzer_eval ( ptr ) ; // expected-warning{{TRUE}}
2013-05-02 02:19:59 +08:00
clang_analyzer_eval ( & castsToBool ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( " abc " ) ; // expected-warning{{TRUE}}
extern float globalFloat ;
clang_analyzer_eval ( globalFloat ) ; // expected-warning{{UNKNOWN}}
}
2017-03-28 23:57:12 +08:00
void locAsIntegerCasts ( void * p ) {
int x = ( int ) p ;
clang_analyzer_eval ( + + x < 10 ) ; // no-crash // expected-warning{{UNKNOWN}}
}
2017-10-14 04:11:00 +08:00
void multiDimensionalArrayPointerCasts ( ) {
static int x [ 10 ] [ 10 ] ;
int * y1 = & ( x [ 3 ] [ 5 ] ) ;
char * z = ( ( char * ) y1 ) + 2 ;
int * y2 = ( int * ) ( z - 2 ) ;
int * y3 = ( ( int * ) x ) + 35 ; // This is offset for [3][5].
clang_analyzer_eval ( y1 = = y2 ) ; // expected-warning{{TRUE}}
// FIXME: should be FALSE (i.e. equal pointers).
clang_analyzer_eval ( y1 - y2 ) ; // expected-warning{{UNKNOWN}}
// FIXME: should be TRUE (i.e. same symbol).
clang_analyzer_eval ( * y1 = = * y2 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( * ( ( char * ) y1 ) = = * ( ( char * ) y2 ) ) ; // expected-warning{{TRUE}}
clang_analyzer_eval ( y1 = = y3 ) ; // expected-warning{{TRUE}}
// FIXME: should be FALSE (i.e. equal pointers).
clang_analyzer_eval ( y1 - y3 ) ; // expected-warning{{UNKNOWN}}
// FIXME: should be TRUE (i.e. same symbol).
clang_analyzer_eval ( * y1 = = * y3 ) ; // expected-warning{{UNKNOWN}}
clang_analyzer_eval ( * ( ( char * ) y1 ) = = * ( ( char * ) y3 ) ) ; // expected-warning{{TRUE}}
}