2010-07-27 09:37:31 +08:00
// RUN: %clang_cc1 -analyze -Wwrite-strings -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-experimental-checks -verify %s
// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -Wwrite-strings -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-experimental-checks -verify %s
// RUN: %clang_cc1 -analyze -DVARIANT -Wwrite-strings -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-experimental-checks -verify %s
// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -Wwrite-strings -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-experimental-checks -verify %s
//===----------------------------------------------------------------------===
// Declarations
//===----------------------------------------------------------------------===
// Some functions are so similar to each other that they follow the same code
// path, such as memcpy and __memcpy_chk, or memcmp and bcmp. If VARIANT is
// defined, make sure to use the variants instead to make sure they are still
// checked by the analyzer.
// Some functions are implemented as builtins. These should be #defined as
// BUILTIN(f), which will prepend "__builtin_" if USE_BUILTINS is defined.
// Functions that have variants and are also availabe as builtins should be
// declared carefully! See memcpy() for an example.
# ifdef USE_BUILTINS
# define BUILTIN(f) __builtin_ ## f
# else /* USE_BUILTINS */
# define BUILTIN(f) f
# endif /* USE_BUILTINS */
typedef typeof ( sizeof ( int ) ) size_t ;
//===----------------------------------------------------------------------===
// strlen()
//===----------------------------------------------------------------------===
# define strlen BUILTIN(strlen)
size_t strlen ( const char * s ) ;
void strlen_constant0 ( ) {
if ( strlen ( " 123 " ) ! = 3 )
2010-07-28 07:30:21 +08:00
( void ) * ( char * ) 0 ;
2010-07-27 09:37:31 +08:00
}
void strlen_constant1 ( ) {
const char * a = " 123 " ;
if ( strlen ( a ) ! = 3 )
2010-07-28 07:30:21 +08:00
( void ) * ( char * ) 0 ;
2010-07-27 09:37:31 +08:00
}
void strlen_constant2 ( char x ) {
char a [ ] = " 123 " ;
a [ 0 ] = x ;
if ( strlen ( a ) ! = 3 )
( void ) * ( char * ) 0 ; // expected-warning{{null}}
}
size_t strlen_null ( ) {
return strlen ( 0 ) ; // expected-warning{{Null pointer argument in call to byte string function}}
}
size_t strlen_fn ( ) {
return strlen ( ( char * ) & strlen_fn ) ; // expected-warning{{Argument to byte string function is the address of the function 'strlen_fn', which is not a null-terminated string}}
}
size_t strlen_nonloc ( ) {
label :
return strlen ( ( char * ) & & label ) ; // expected-warning{{Argument to byte string function is the address of the label 'label', which is not a null-terminated string}}
}