2013-07-23 01:55:04 +08:00
// RUN: %clang_cc1 -fsyntax-only -verify %s
2011-06-28 05:12:03 +08:00
// rdar://9584012
typedef struct {
char * str ;
} Class ;
typedef union {
Class * object ;
} Instance __attribute__ ( ( transparent_union ) ) ;
__attribute__ ( ( nonnull ( 1 ) ) ) void Class_init ( Instance this , char * str ) {
this . object - > str = str ;
}
int main ( void ) {
Class * obj ;
2014-08-27 12:59:42 +08:00
Class_init ( 0 , " Hello World " ) ; // expected-warning {{null passed to a callee that requires a non-null argument}}
2011-06-28 05:12:03 +08:00
Class_init ( obj , " Hello World " ) ;
}
2013-07-30 08:48:57 +08:00
void foo ( const char * str ) __attribute__ ( ( nonnull ( " foo " ) ) ) ; // expected-error{{'nonnull' attribute requires parameter 1 to be an integer constant}}
2013-12-27 01:07:49 +08:00
void bar ( int i ) __attribute__ ( ( nonnull ( 1 ) ) ) ; // expected-warning {{'nonnull' attribute only applies to pointer arguments}} expected-warning {{'nonnull' attribute applied to function with no pointer arguments}}
2014-01-17 14:24:56 +08:00
void baz ( __attribute__ ( ( nonnull ) ) const char * str ) ;
void baz2 ( __attribute__ ( ( nonnull ( 1 ) ) ) const char * str ) ; // expected-warning {{'nonnull' attribute when used on parameters takes no arguments}}
void baz3 ( __attribute__ ( ( nonnull ) ) int x ) ; // expected-warning {{'nonnull' attribute only applies to pointer arguments}}
void test_baz ( ) {
2014-08-27 12:59:42 +08:00
baz ( 0 ) ; // expected-warning {{null passed to a callee that requires a non-null argument}}
2014-01-17 14:24:56 +08:00
baz2 ( 0 ) ; // no-warning
baz3 ( 0 ) ; // no-warning
}
2014-01-20 22:19:44 +08:00
void test_void_returns_nonnull ( void ) __attribute__ ( ( returns_nonnull ) ) ; // expected-warning {{'returns_nonnull' attribute only applies to return values that are pointers}}
int test_int_returns_nonnull ( void ) __attribute__ ( ( returns_nonnull ) ) ; // expected-warning {{'returns_nonnull' attribute only applies to return values that are pointers}}
void * test_ptr_returns_nonnull ( void ) __attribute__ ( ( returns_nonnull ) ) ; // no-warning
2014-01-20 13:50:47 +08:00
2014-01-17 22:38:58 +08:00
int i __attribute__ ( ( nonnull ) ) ; // expected-warning {{'nonnull' attribute only applies to functions, methods, and parameters}}
2014-01-20 13:50:47 +08:00
int j __attribute__ ( ( returns_nonnull ) ) ; // expected-warning {{'returns_nonnull' attribute only applies to functions and methods}}
2014-07-12 00:31:29 +08:00
void * test_no_fn_proto ( ) __attribute__ ( ( returns_nonnull ) ) ; // no-warning
void * test_with_fn_proto ( void ) __attribute__ ( ( returns_nonnull ) ) ; // no-warning
2014-01-22 14:10:28 +08:00
__attribute__ ( ( returns_nonnull ) )
void * test_bad_returns_null ( void ) {
return 0 ; // expected-warning {{null returned from function that requires a non-null return value}}
}
2014-02-12 01:27:59 +08:00
void PR18795 ( int ( * g ) ( const char * h , . . . ) __attribute__ ( ( nonnull ( 1 ) ) ) __attribute__ ( ( nonnull ) ) ) {
2014-08-27 12:59:42 +08:00
g ( 0 ) ; // expected-warning{{null passed to a callee that requires a non-null argument}}
2014-02-12 01:27:59 +08:00
}
void PR18795_helper ( ) {
2014-08-27 12:59:42 +08:00
PR18795 ( 0 ) ; // expected-warning{{null passed to a callee that requires a non-null argument}}
2014-02-12 01:27:59 +08:00
}
2014-08-27 12:59:42 +08:00
void vararg1 ( int n , . . . ) __attribute__ ( ( nonnull ( 2 ) ) ) ;
void vararg1_test ( ) {
vararg1 ( 0 ) ;
vararg1 ( 1 , ( void * ) 0 ) ; // expected-warning{{null passed}}
vararg1 ( 2 , ( void * ) 0 , ( void * ) 0 ) ; // expected-warning{{null passed}}
vararg1 ( 2 , ( void * ) & vararg1 , ( void * ) 0 ) ;
}
void vararg2 ( int n , . . . ) __attribute__ ( ( nonnull , nonnull , nonnull ) ) ;
void vararg2_test ( ) {
vararg2 ( 0 ) ;
vararg2 ( 1 , ( void * ) 0 ) ; // expected-warning{{null passed}}
vararg2 ( 2 , ( void * ) 0 , ( void * ) 0 ) ; // expected-warning 2{{null passed}}
}
2014-02-12 01:27:59 +08:00
2014-08-27 12:59:42 +08:00
void vararg3 ( int n , . . . ) __attribute__ ( ( nonnull , nonnull ( 2 ) , nonnull ( 3 ) ) ) ;
void vararg3_test ( ) {
vararg3 ( 0 ) ;
vararg3 ( 1 , ( void * ) 0 ) ; // expected-warning{{null passed}}
vararg3 ( 2 , ( void * ) 0 , ( void * ) 0 ) ; // expected-warning 2{{null passed}}
}
void redecl ( void * , void * ) ;
void redecl ( void * , void * ) __attribute__ ( ( nonnull ( 1 ) ) ) ;
void redecl ( void * , void * ) __attribute__ ( ( nonnull ( 2 ) ) ) ;
void redecl ( void * , void * ) ;
void redecl_test ( void * p ) {
redecl ( p , 0 ) ; // expected-warning{{null passed}}
redecl ( 0 , p ) ; // expected-warning{{null passed}}
}
2014-11-19 05:57:54 +08:00
// rdar://18712242
# define NULL (void*)0
2016-06-15 13:18:39 +08:00
__attribute__ ( ( __nonnull__ ) ) // expected-note 2{{declared 'nonnull' here}}
2014-11-19 05:57:54 +08:00
int evil_nonnull_func ( int * pointer , void * pv )
{
2015-12-09 06:02:00 +08:00
if ( pointer = = NULL ) { // expected-warning {{comparison of nonnull parameter 'pointer' equal to a null pointer is 'false' on first encounter}}
2014-11-19 05:57:54 +08:00
return 0 ;
} else {
return * pointer ;
}
pointer = pv ;
if ( ! pointer )
return 0 ;
else
return * pointer ;
2015-12-09 06:02:00 +08:00
if ( pv = = NULL ) { } // expected-warning {{comparison of nonnull parameter 'pv' equal to a null pointer is 'false' on first encounter}}
2014-11-19 05:57:54 +08:00
}
void set_param_to_null ( int * * ) ;
2016-06-15 13:18:39 +08:00
int another_evil_nonnull_func ( int * pointer , char ch , void * pv ) __attribute__ ( ( nonnull ( 1 , 3 ) ) ) ; // expected-note 2{{declared 'nonnull' here}}
2014-11-19 05:57:54 +08:00
int another_evil_nonnull_func ( int * pointer , char ch , void * pv ) {
2015-12-09 06:02:00 +08:00
if ( pointer = = NULL ) { // expected-warning {{comparison of nonnull parameter 'pointer' equal to a null pointer is 'false' on first encounter}}
2014-11-19 05:57:54 +08:00
return 0 ;
} else {
return * pointer ;
}
set_param_to_null ( & pointer ) ;
if ( ! pointer )
return 0 ;
else
return * pointer ;
2015-12-09 06:02:00 +08:00
if ( pv = = NULL ) { } // expected-warning {{comparison of nonnull parameter 'pv' equal to a null pointer is 'false' on first encounter}}
2014-11-19 05:57:54 +08:00
}
extern void * returns_null ( void * * ) ;
extern void FOO ( ) ;
extern void FEE ( ) ;
extern void * pv ;
2016-06-15 13:18:39 +08:00
__attribute__ ( ( __nonnull__ ) ) // expected-note {{declared 'nonnull' here}}
2014-11-19 05:57:54 +08:00
void yet_another_evil_nonnull_func ( int * pointer )
{
while ( pv ) {
// This comparison will not be optimized away.
if ( pointer ) { // expected-warning {{nonnull parameter 'pointer' will evaluate to 'true' on first encounter}}
FOO ( ) ;
} else {
FEE ( ) ;
}
pointer = returns_null ( & pv ) ;
}
}
2016-06-15 13:18:39 +08:00
void pr21668_1 ( __attribute__ ( ( nonnull ) ) const char * p , const char * s ) { // expected-note {{declared 'nonnull' here}}
2014-12-12 03:35:42 +08:00
if ( p ) // expected-warning {{nonnull parameter 'p' will evaluate to 'true' on first encounter}}
;
if ( s ) // No warning
;
}
void pr21668_2 ( __attribute__ ( ( nonnull ) ) const char * p ) {
p = 0 ;
if ( p ) // No warning
;
}
2015-12-09 06:02:00 +08:00
2016-06-15 13:18:39 +08:00
__attribute__ ( ( returns_nonnull ) ) void * returns_nonnull_whee ( ) ; // expected-note 6{{declared 'returns_nonnull' here}}
2015-12-09 06:02:00 +08:00
void returns_nonnull_warning_tests ( ) {
if ( returns_nonnull_whee ( ) = = NULL ) { } // expected-warning {{comparison of nonnull function call 'returns_nonnull_whee()' equal to a null pointer is 'false' on first encounter}}
if ( returns_nonnull_whee ( ) ! = NULL ) { } // expected-warning {{comparison of nonnull function call 'returns_nonnull_whee()' not equal to a null pointer is 'true' on first encounter}}
if ( returns_nonnull_whee ( ) ) { } // expected-warning {{nonnull function call 'returns_nonnull_whee()' will evaluate to 'true' on first encounter}}
if ( ! returns_nonnull_whee ( ) ) { } // expected-warning {{nonnull function call 'returns_nonnull_whee()' will evaluate to 'true' on first encounter}}
int and_again = ! returns_nonnull_whee ( ) ; // expected-warning {{nonnull function call 'returns_nonnull_whee()' will evaluate to 'true' on first encounter}}
and_again = ! returns_nonnull_whee ( ) ; // expected-warning {{nonnull function call 'returns_nonnull_whee()' will evaluate to 'true' on first encounter}}
}