1 | // RUN: %clang_analyze_cc1 -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 | |