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