2020-02-16 22:01:25 +08:00
// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin9 -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -Wno-pointer-to-int-cast -verify -analyzer-config eagerly-assume=false %s
// RUN: %clang_analyze_cc1 -triple i386-apple-darwin9 -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -Wno-pointer-to-int-cast -verify -analyzer-config eagerly-assume=false %s
// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin9 -analyzer-checker=core,alpha.core,debug.ExprInspection -Wno-pointer-to-int-cast -verify -DEAGERLY_ASSUME=1 -w %s
// RUN: %clang_analyze_cc1 -triple i386-apple-darwin9 -analyzer-checker=core,alpha.core,debug.ExprInspection -Wno-pointer-to-int-cast -verify -DEAGERLY_ASSUME=1 -DBIT32=1 -w %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 ( ) ;
2018-08-30 04:29:59 +08:00
# ifndef EAGERLY_ASSUME
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}}
}
2018-05-05 06:11:12 +08:00
void * getVoidPtr ( ) ;
void testCastVoidPtrToIntPtrThroughIntTypedAssignment ( ) {
int * x ;
( * ( ( int * ) ( & x ) ) ) = ( int ) getVoidPtr ( ) ;
* x = 1 ; // no-crash
}
void testCastUIntPtrToIntPtrThroughIntTypedAssignment ( ) {
unsigned u ;
int * x ;
( * ( ( int * ) ( & x ) ) ) = ( int ) & u ;
* x = 1 ;
clang_analyzer_eval ( u = = 1 ) ; // expected-warning{{TRUE}}
}
void testCastVoidPtrToIntPtrThroughUIntTypedAssignment ( ) {
int * x ;
( * ( ( int * ) ( & x ) ) ) = ( int ) ( unsigned * ) getVoidPtr ( ) ;
* x = 1 ; // no-crash
}
2018-07-24 07:09:44 +08:00
void testLocNonLocSymbolAssume ( int a , int * b ) {
2018-07-24 07:48:13 +08:00
if ( ( int ) b < a ) { } // no-crash
2018-07-24 07:09:44 +08:00
}
2018-08-01 03:26:34 +08:00
void testLocNonLocSymbolRemainder ( int a , int * b ) {
int c = ( ( int ) b ) % a ;
if ( a = = 1 ) {
c + = 1 ;
}
}
2018-08-07 10:27:38 +08:00
void testSwitchWithSizeofs ( ) {
switch ( sizeof ( char ) = = 1 ) { // expected-warning{{switch condition has boolean value}}
case sizeof ( char ) : ; // no-crash
}
}
2018-08-30 04:29:59 +08:00
# endif
# ifdef EAGERLY_ASSUME
2018-08-30 05:18:47 +08:00
int globalA ;
2018-08-30 04:29:59 +08:00
extern int globalFunc ( ) ;
void no_crash_on_symsym_cast_to_long ( ) {
char c = globalFunc ( ) - 5 ;
c = = 0 ;
globalA - = c ;
globalA = = 3 ;
2018-08-30 05:18:47 +08:00
( long ) globalA < < 48 ;
# ifdef BIT32
// expected-warning@-2{{The result of the left shift is undefined due to shifting by '48', which is greater or equal to the width of type 'long'}}
# else
// expected-no-diagnostics
# endif
2018-08-30 04:29:59 +08:00
}
# endif
2018-12-22 10:06:51 +08:00
char no_crash_SymbolCast_of_float_type_aux ( int * p ) {
* p + = 1 ;
return * p ;
}
void no_crash_SymbolCast_of_float_type ( ) {
extern float x ;
char ( * f ) ( ) = no_crash_SymbolCast_of_float_type_aux ;
f ( & x ) ;
}
double no_crash_reinterpret_double_as_int ( double a ) {
* ( int * ) & a = 1 ;
return a * a ;
}
double no_crash_reinterpret_double_as_ptr ( double a ) {
* ( void * * ) & a = 0 ;
return a * a ;
}
double no_crash_reinterpret_double_as_sym_int ( double a , int b ) {
* ( int * ) & a = b ;
return a * a ;
}
double no_crash_reinterpret_double_as_sym_ptr ( double a , void * b ) {
* ( void * * ) & a = b ;
return a * a ;
}