Home | History | Annotate | Download | only in Analysis
      1 // RUN: %clang_cc1 -analyze -analyzer-checker=core -w -verify %s
      2 
      3 @interface MyObject
      4 - (void)takePointer:(void *)ptr __attribute__((nonnull(1)));
      5 - (void)takePointerArg:(void *)__attribute__((nonnull)) ptr;
      6 
      7 @end
      8 
      9 void testNonNullMethod(int *p, MyObject *obj) {
     10   if (p)
     11     return;
     12   [obj takePointer:p]; // expected-warning{{nonnull}}
     13 }
     14 
     15 
     16 @interface Subclass : MyObject
     17 // [[nonnull]] is an inherited attribute.
     18 - (void)takePointer:(void *)ptr;
     19 @end
     20 
     21 void testSubclass(int *p, Subclass *obj) {
     22   if (p)
     23     return;
     24   [obj takePointer:p]; // expected-warning{{nonnull}}
     25 }
     26 
     27 void testSubclassArg(int *p, Subclass *obj) {
     28   if (p)
     29     return;
     30   [obj takePointerArg:p]; // expected-warning{{nonnull}}
     31 }
     32 
     33 
     34 union rdar16153464_const_cp_t {
     35   const struct rdar16153464_cczp *zp;
     36   const struct rdar16153464_cczp_prime *prime;
     37 } __attribute__((transparent_union));
     38 
     39 struct rdar16153464_header {
     40   union rdar16153464_const_cp_t cp;
     41   unsigned char pad[16 - sizeof(union rdar16153464_const_cp_t *)];
     42 } __attribute__((aligned(16)));
     43 
     44 
     45 struct rdar16153464_full_ctx {
     46   struct rdar16153464_header hdr;
     47 } __attribute__((aligned(16)));
     48 
     49 
     50 struct rdar16153464_pub_ctx {
     51   struct rdar16153464_header hdr;
     52 } __attribute__((aligned(16)));
     53 
     54 
     55 union rdar16153464_full_ctx_t {
     56   struct rdar16153464_full_ctx *_full;
     57   struct rdar16153464_header *hdr;
     58   struct rdar16153464_body *body;
     59   struct rdar16153464_public *pub;
     60 } __attribute__((transparent_union));
     61 
     62 union rdar16153464_pub_ctx_t {
     63   struct rdar16153464_pub_ctx *_pub;
     64   struct rdar16153464_full_ctx *_full;
     65   struct rdar16153464_header *hdr;
     66   struct rdar16153464_body *body;
     67   struct rdar16153464_public *pub;
     68   union rdar16153464_full_ctx_t innert;
     69 } __attribute__((transparent_union));
     70 
     71 int rdar16153464(union rdar16153464_full_ctx_t inner)
     72 {
     73   extern void rdar16153464_check(union rdar16153464_pub_ctx_t outer) __attribute((nonnull(1)));
     74   rdar16153464_check((union rdar16153464_pub_ctx_t){ .innert = inner }); // no-warning
     75   rdar16153464_check(inner); // no-warning
     76   rdar16153464_check(0); // expected-warning{{nonnull}}
     77 }
     78 
     79 // Multiple attributes, the basic case
     80 void multipleAttributes_1(char *p, char *q) __attribute((nonnull(1))) __attribute((nonnull(2)));
     81 
     82 void testMultiple_1(void) {
     83   char c;
     84   multipleAttributes_1(&c, &c); // no-warning
     85 }
     86 
     87 void testMultiple_2(void) {
     88   char c;
     89   multipleAttributes_1(0, &c); // expected-warning{{nonnull}}
     90 }
     91 
     92 void testMultiple_3(void) {
     93   char c;
     94   multipleAttributes_1(&c, 0); // expected-warning{{nonnull}}
     95 }
     96 
     97 void testMultiple_4(void) {
     98   multipleAttributes_1(0, 0);// expected-warning{{nonnull}}
     99 }
    100 
    101 // Multiple attributes, multiple prototypes
    102 void multipleAttributes_2(char *p, char *q) __attribute((nonnull(1)));
    103 void multipleAttributes_2(char *p, char *q) __attribute((nonnull(2)));
    104 
    105 void testMultiple_5(void) {
    106   char c;
    107   multipleAttributes_2(0, &c);// expected-warning{{nonnull}}
    108 }
    109 
    110 void testMultiple_6(void) {
    111   char c;
    112   multipleAttributes_2(&c, 0);// expected-warning{{nonnull}}
    113 }
    114 
    115 void testMultiple_7(void) {
    116   multipleAttributes_2(0, 0);// expected-warning{{nonnull}}
    117 }
    118 
    119 // Multiple attributes, same index
    120 void multipleAttributes_3(char *p, char *q) __attribute((nonnull(1))) __attribute((nonnull(1)));
    121 
    122 void testMultiple_8(void) {
    123   char c;
    124   multipleAttributes_3(0, &c); // expected-warning{{nonnull}}
    125 }
    126 
    127 void testMultiple_9(void) {
    128   char c;
    129   multipleAttributes_3(&c, 0); // no-warning
    130 }
    131 
    132 // Multiple attributes, the middle argument is missing an attribute
    133 void multipleAttributes_4(char *p, char *q, char *r) __attribute((nonnull(1))) __attribute((nonnull(3)));
    134 
    135 void testMultiple_10(void) {
    136   char c;
    137   multipleAttributes_4(0, &c, &c); // expected-warning{{nonnull}}
    138 }
    139 
    140 void testMultiple_11(void) {
    141   char c;
    142   multipleAttributes_4(&c, 0, &c); // no-warning
    143 }
    144 
    145 void testMultiple_12(void) {
    146   char c;
    147   multipleAttributes_4(&c, &c, 0); // expected-warning{{nonnull}}
    148 }
    149 
    150 
    151 // Multiple attributes, when the last is without index
    152 void multipleAttributes_all_1(char *p, char *q) __attribute((nonnull(1))) __attribute((nonnull));
    153 
    154 void testMultiple_13(void) {
    155   char c;
    156   multipleAttributes_all_1(0, &c); // expected-warning{{nonnull}}
    157 }
    158 
    159 void testMultiple_14(void) {
    160   char c;
    161   multipleAttributes_all_1(&c, 0); // expected-warning{{nonnull}}
    162 }
    163 
    164 // Multiple attributes, when the first is without index
    165 void multipleAttributes_all_2(char *p, char *q) __attribute((nonnull)) __attribute((nonnull(2)));
    166 
    167 void testMultiple_15(void) {
    168   char c;
    169   multipleAttributes_all_2(0, &c); // expected-warning{{nonnull}}
    170 }
    171 
    172 void testMultiple_16(void) {
    173   char c;
    174   multipleAttributes_all_2(&c, 0); // expected-warning{{nonnull}}
    175 }
    176 
    177 void testVararg(int k, void *p) {
    178   extern void testVararg_check(int, ...) __attribute__((nonnull));
    179   void *n = 0;
    180   testVararg_check(0);
    181   testVararg_check(1, p);
    182   if (k == 1)
    183     testVararg_check(1, n); // expected-warning{{nonnull}}
    184   testVararg_check(2, p, p);
    185   if (k == 2)
    186     testVararg_check(2, n, p); // expected-warning{{nonnull}}
    187   if (k == 3)
    188     testVararg_check(2, p, n); // expected-warning{{nonnull}}
    189 }
    190 
    191 void testNotPtr() {
    192   struct S { int a; int b; int c; } s = {};
    193   extern void testNotPtr_check(struct S, int) __attribute__((nonnull(1, 2)));
    194   testNotPtr_check(s, 0);
    195 }
    196