Home | History | Annotate | Download | only in Sema
      1 // RUN: %clang_cc1 -fsyntax-only -verify %s
      2 // rdar://9584012
      3 
      4 typedef struct {
      5 	char *str;
      6 } Class;
      7 
      8 typedef union {
      9 	Class *object;
     10 } Instance __attribute__((transparent_union));
     11 
     12 __attribute__((nonnull(1))) void Class_init(Instance this, char *str) {
     13 	this.object->str = str;
     14 }
     15 
     16 int main(void) {
     17 	Class *obj;
     18 	Class_init(0, "Hello World"); // expected-warning {{null passed to a callee that requires a non-null argument}}
     19 	Class_init(obj, "Hello World");
     20 }
     21 
     22 void foo(const char *str) __attribute__((nonnull("foo"))); // expected-error{{'nonnull' attribute requires parameter 1 to be an integer constant}}
     23 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}}
     24 
     25 void baz(__attribute__((nonnull)) const char *str);
     26 void baz2(__attribute__((nonnull(1))) const char *str); // expected-warning {{'nonnull' attribute when used on parameters takes no arguments}}
     27 void baz3(__attribute__((nonnull)) int x); // expected-warning {{'nonnull' attribute only applies to pointer arguments}}
     28 
     29 void test_baz() {
     30   baz(0); // expected-warning {{null passed to a callee that requires a non-null argument}}
     31   baz2(0); // no-warning
     32   baz3(0); // no-warning
     33 }
     34 
     35 void test_void_returns_nonnull(void) __attribute__((returns_nonnull)); // expected-warning {{'returns_nonnull' attribute only applies to return values that are pointers}}
     36 int test_int_returns_nonnull(void) __attribute__((returns_nonnull)); // expected-warning {{'returns_nonnull' attribute only applies to return values that are pointers}}
     37 void *test_ptr_returns_nonnull(void) __attribute__((returns_nonnull)); // no-warning
     38 
     39 int i __attribute__((nonnull)); // expected-warning {{'nonnull' attribute only applies to functions, methods, and parameters}}
     40 int j __attribute__((returns_nonnull)); // expected-warning {{'returns_nonnull' attribute only applies to functions and methods}}
     41 void *test_no_fn_proto() __attribute__((returns_nonnull)); // no-warning
     42 void *test_with_fn_proto(void) __attribute__((returns_nonnull)); // no-warning
     43 
     44 __attribute__((returns_nonnull))
     45 void *test_bad_returns_null(void) {
     46   return 0; // expected-warning {{null returned from function that requires a non-null return value}}
     47 }
     48 
     49 void PR18795(int (*g)(const char *h, ...) __attribute__((nonnull(1))) __attribute__((nonnull))) {
     50   g(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
     51 }
     52 void PR18795_helper() {
     53   PR18795(0); // expected-warning{{null passed to a callee that requires a non-null argument}}
     54 }
     55 
     56 void vararg1(int n, ...) __attribute__((nonnull(2)));
     57 void vararg1_test() {
     58   vararg1(0);
     59   vararg1(1, (void*)0); // expected-warning{{null passed}}
     60   vararg1(2, (void*)0, (void*)0); // expected-warning{{null passed}}
     61   vararg1(2, (void*)&vararg1, (void*)0);
     62 }
     63 
     64 void vararg2(int n, ...) __attribute__((nonnull, nonnull, nonnull));
     65 void vararg2_test() {
     66   vararg2(0);
     67   vararg2(1, (void*)0); // expected-warning{{null passed}}
     68   vararg2(2, (void*)0, (void*)0); // expected-warning 2{{null passed}}
     69 }
     70 
     71 void vararg3(int n, ...) __attribute__((nonnull, nonnull(2), nonnull(3)));
     72 void vararg3_test() {
     73   vararg3(0);
     74   vararg3(1, (void*)0); // expected-warning{{null passed}}
     75   vararg3(2, (void*)0, (void*)0); // expected-warning 2{{null passed}}
     76 }
     77 
     78 void redecl(void *, void *);
     79 void redecl(void *, void *) __attribute__((nonnull(1)));
     80 void redecl(void *, void *) __attribute__((nonnull(2)));
     81 void redecl(void *, void *);
     82 void redecl_test(void *p) {
     83   redecl(p, 0); // expected-warning{{null passed}}
     84   redecl(0, p); // expected-warning{{null passed}}
     85 }
     86 
     87 // rdar://18712242
     88 #define NULL (void*)0
     89 __attribute__((__nonnull__))  // expected-note 2{{declared 'nonnull' here}}
     90 int evil_nonnull_func(int* pointer, void * pv)
     91 {
     92    if (pointer == NULL) {  // expected-warning {{comparison of nonnull parameter 'pointer' equal to a null pointer is 'false' on first encounter}}
     93      return 0;
     94    } else {
     95      return *pointer;
     96    }
     97 
     98    pointer = pv;
     99    if (!pointer)
    100      return 0;
    101    else
    102      return *pointer;
    103 
    104    if (pv == NULL) {} // expected-warning {{comparison of nonnull parameter 'pv' equal to a null pointer is 'false' on first encounter}}
    105 }
    106 
    107 void set_param_to_null(int**);
    108 int another_evil_nonnull_func(int* pointer, char ch, void * pv) __attribute__((nonnull(1, 3)));  // expected-note 2{{declared 'nonnull' here}}
    109 int another_evil_nonnull_func(int* pointer, char ch, void * pv) {
    110    if (pointer == NULL) { // expected-warning {{comparison of nonnull parameter 'pointer' equal to a null pointer is 'false' on first encounter}}
    111      return 0;
    112    } else {
    113      return *pointer;
    114    }
    115 
    116    set_param_to_null(&pointer);
    117    if (!pointer)
    118      return 0;
    119    else
    120      return *pointer;
    121 
    122    if (pv == NULL) {} // expected-warning {{comparison of nonnull parameter 'pv' equal to a null pointer is 'false' on first encounter}}
    123 }
    124 
    125 extern void *returns_null(void**);
    126 extern void FOO();
    127 extern void FEE();
    128 
    129 extern void *pv;
    130 __attribute__((__nonnull__))  // expected-note {{declared 'nonnull' here}}
    131 void yet_another_evil_nonnull_func(int* pointer)
    132 {
    133  while (pv) {
    134    // This comparison will not be optimized away.
    135    if (pointer) {  // expected-warning {{nonnull parameter 'pointer' will evaluate to 'true' on first encounter}}
    136      FOO();
    137    } else {
    138      FEE();
    139    }
    140    pointer = returns_null(&pv);
    141  }
    142 }
    143 
    144 void pr21668_1(__attribute__((nonnull)) const char *p, const char *s) { // expected-note {{declared 'nonnull' here}}
    145   if (p) // expected-warning {{nonnull parameter 'p' will evaluate to 'true' on first encounter}}
    146     ;
    147   if (s) // No warning
    148     ;
    149 }
    150 
    151 void pr21668_2(__attribute__((nonnull)) const char *p) {
    152   p = 0;
    153   if (p) // No warning
    154     ;
    155 }
    156 
    157 __attribute__((returns_nonnull)) void *returns_nonnull_whee();  // expected-note 6{{declared 'returns_nonnull' here}}
    158 
    159 void returns_nonnull_warning_tests() {
    160   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}}
    161 
    162   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}}
    163 
    164   if (returns_nonnull_whee()) {} // expected-warning {{nonnull function call 'returns_nonnull_whee()' will evaluate to 'true' on first encounter}}
    165   if (!returns_nonnull_whee()) {} // expected-warning {{nonnull function call 'returns_nonnull_whee()' will evaluate to 'true' on first encounter}}
    166 
    167   int and_again = !returns_nonnull_whee(); // expected-warning {{nonnull function call 'returns_nonnull_whee()' will evaluate to 'true' on first encounter}}
    168   and_again = !returns_nonnull_whee(); // expected-warning {{nonnull function call 'returns_nonnull_whee()' will evaluate to 'true' on first encounter}}
    169 }
    170