| // RUN: %clang_analyze_cc1 -analyzer-checker=core -w -verify %s |
| |
| @interface MyObject |
| - (void)takePointer:(void *)ptr __attribute__((nonnull(1))); |
| - (void)takePointerArg:(void *)__attribute__((nonnull)) ptr; |
| |
| @end |
| |
| void testNonNullMethod(int *p, MyObject *obj) { |
| if (p) |
| return; |
| [obj takePointer:p]; // expected-warning{{nonnull}} |
| } |
| |
| |
| @interface Subclass : MyObject |
| // [[nonnull]] is an inherited attribute. |
| - (void)takePointer:(void *)ptr; |
| @end |
| |
| void testSubclass(int *p, Subclass *obj) { |
| if (p) |
| return; |
| [obj takePointer:p]; // expected-warning{{nonnull}} |
| } |
| |
| void testSubclassArg(int *p, Subclass *obj) { |
| if (p) |
| return; |
| [obj takePointerArg:p]; // expected-warning{{nonnull}} |
| } |
| |
| |
| union rdar16153464_const_cp_t { |
| const struct rdar16153464_cczp *zp; |
| const struct rdar16153464_cczp_prime *prime; |
| } __attribute__((transparent_union)); |
| |
| struct rdar16153464_header { |
| union rdar16153464_const_cp_t cp; |
| unsigned char pad[16 - sizeof(union rdar16153464_const_cp_t *)]; |
| } __attribute__((aligned(16))); |
| |
| |
| struct rdar16153464_full_ctx { |
| struct rdar16153464_header hdr; |
| } __attribute__((aligned(16))); |
| |
| |
| struct rdar16153464_pub_ctx { |
| struct rdar16153464_header hdr; |
| } __attribute__((aligned(16))); |
| |
| |
| union rdar16153464_full_ctx_t { |
| struct rdar16153464_full_ctx *_full; |
| struct rdar16153464_header *hdr; |
| struct rdar16153464_body *body; |
| struct rdar16153464_public *pub; |
| } __attribute__((transparent_union)); |
| |
| union rdar16153464_pub_ctx_t { |
| struct rdar16153464_pub_ctx *_pub; |
| struct rdar16153464_full_ctx *_full; |
| struct rdar16153464_header *hdr; |
| struct rdar16153464_body *body; |
| struct rdar16153464_public *pub; |
| union rdar16153464_full_ctx_t innert; |
| } __attribute__((transparent_union)); |
| |
| int rdar16153464(union rdar16153464_full_ctx_t inner) |
| { |
| extern void rdar16153464_check(union rdar16153464_pub_ctx_t outer) __attribute((nonnull(1))); |
| rdar16153464_check((union rdar16153464_pub_ctx_t){ .innert = inner }); // no-warning |
| rdar16153464_check(inner); // no-warning |
| rdar16153464_check(0); // expected-warning{{nonnull}} |
| } |
| |
| // Multiple attributes, the basic case |
| void multipleAttributes_1(char *p, char *q) __attribute((nonnull(1))) __attribute((nonnull(2))); |
| |
| void testMultiple_1(void) { |
| char c; |
| multipleAttributes_1(&c, &c); // no-warning |
| } |
| |
| void testMultiple_2(void) { |
| char c; |
| multipleAttributes_1(0, &c); // expected-warning{{nonnull}} |
| } |
| |
| void testMultiple_3(void) { |
| char c; |
| multipleAttributes_1(&c, 0); // expected-warning{{nonnull}} |
| } |
| |
| void testMultiple_4(void) { |
| multipleAttributes_1(0, 0);// expected-warning{{nonnull}} |
| } |
| |
| // Multiple attributes, multiple prototypes |
| void multipleAttributes_2(char *p, char *q) __attribute((nonnull(1))); |
| void multipleAttributes_2(char *p, char *q) __attribute((nonnull(2))); |
| |
| void testMultiple_5(void) { |
| char c; |
| multipleAttributes_2(0, &c);// expected-warning{{nonnull}} |
| } |
| |
| void testMultiple_6(void) { |
| char c; |
| multipleAttributes_2(&c, 0);// expected-warning{{nonnull}} |
| } |
| |
| void testMultiple_7(void) { |
| multipleAttributes_2(0, 0);// expected-warning{{nonnull}} |
| } |
| |
| // Multiple attributes, same index |
| void multipleAttributes_3(char *p, char *q) __attribute((nonnull(1))) __attribute((nonnull(1))); |
| |
| void testMultiple_8(void) { |
| char c; |
| multipleAttributes_3(0, &c); // expected-warning{{nonnull}} |
| } |
| |
| void testMultiple_9(void) { |
| char c; |
| multipleAttributes_3(&c, 0); // no-warning |
| } |
| |
| // Multiple attributes, the middle argument is missing an attribute |
| void multipleAttributes_4(char *p, char *q, char *r) __attribute((nonnull(1))) __attribute((nonnull(3))); |
| |
| void testMultiple_10(void) { |
| char c; |
| multipleAttributes_4(0, &c, &c); // expected-warning{{nonnull}} |
| } |
| |
| void testMultiple_11(void) { |
| char c; |
| multipleAttributes_4(&c, 0, &c); // no-warning |
| } |
| |
| void testMultiple_12(void) { |
| char c; |
| multipleAttributes_4(&c, &c, 0); // expected-warning{{nonnull}} |
| } |
| |
| |
| // Multiple attributes, when the last is without index |
| void multipleAttributes_all_1(char *p, char *q) __attribute((nonnull(1))) __attribute((nonnull)); |
| |
| void testMultiple_13(void) { |
| char c; |
| multipleAttributes_all_1(0, &c); // expected-warning{{nonnull}} |
| } |
| |
| void testMultiple_14(void) { |
| char c; |
| multipleAttributes_all_1(&c, 0); // expected-warning{{nonnull}} |
| } |
| |
| // Multiple attributes, when the first is without index |
| void multipleAttributes_all_2(char *p, char *q) __attribute((nonnull)) __attribute((nonnull(2))); |
| |
| void testMultiple_15(void) { |
| char c; |
| multipleAttributes_all_2(0, &c); // expected-warning{{nonnull}} |
| } |
| |
| void testMultiple_16(void) { |
| char c; |
| multipleAttributes_all_2(&c, 0); // expected-warning{{nonnull}} |
| } |
| |
| void testVararg(int k, void *p) { |
| extern void testVararg_check(int, ...) __attribute__((nonnull)); |
| void *n = 0; |
| testVararg_check(0); |
| testVararg_check(1, p); |
| if (k == 1) |
| testVararg_check(1, n); // expected-warning{{nonnull}} |
| testVararg_check(2, p, p); |
| if (k == 2) |
| testVararg_check(2, n, p); // expected-warning{{nonnull}} |
| if (k == 3) |
| testVararg_check(2, p, n); // expected-warning{{nonnull}} |
| } |
| |
| void testNotPtr() { |
| struct S { int a; int b; int c; } s = {}; |
| extern void testNotPtr_check(struct S, int) __attribute__((nonnull(1, 2))); |
| testNotPtr_check(s, 0); |
| } |