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