[clang-cl] Ignore /Wv and /Wv:17 flags
[llvm-project.git] / clang / test / Analysis / inlining / false-positive-suppression.c
blob34b84bfd0f405b681ce4c609d771e1035dfc5955
1 // RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config suppress-null-return-paths=false -verify %s
2 // RUN: %clang_analyze_cc1 -analyzer-checker=core -verify -DSUPPRESSED=1 %s
3 // RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config avoid-suppressing-null-argument-paths=true -DSUPPRESSED=1 -DNULL_ARGS=1 -verify %s
5 int opaquePropertyCheck(void *object);
6 int coin(void);
8 int *getNull(void) {
9 return 0;
12 int* getPtr(void);
14 int *dynCastToInt(void *ptr) {
15 if (opaquePropertyCheck(ptr))
16 return (int *)ptr;
17 return 0;
20 int *dynCastOrNull(void *ptr) {
21 if (!ptr)
22 return 0;
23 if (opaquePropertyCheck(ptr))
24 return (int *)ptr;
25 return 0;
29 void testDynCast(void *p) {
30 int *casted = dynCastToInt(p);
31 *casted = 1;
32 #ifndef SUPPRESSED
33 // expected-warning@-2 {{Dereference of null pointer}}
34 #endif
37 void testDynCastOrNull(void *p) {
38 int *casted = dynCastOrNull(p);
39 *casted = 1;
40 #ifndef SUPPRESSED
41 // expected-warning@-2 {{Dereference of null pointer}}
42 #endif
46 void testBranch(void *p) {
47 int *casted;
49 // Although the report will be suppressed on one branch, it should still be
50 // valid on the other.
51 if (coin()) {
52 casted = dynCastToInt(p);
53 } else {
54 if (p)
55 return;
56 casted = (int *)p;
59 *casted = 1; // expected-warning {{Dereference of null pointer}}
62 void testBranchReversed(void *p) {
63 int *casted;
65 // Although the report will be suppressed on one branch, it should still be
66 // valid on the other.
67 if (coin()) {
68 if (p)
69 return;
70 casted = (int *)p;
71 } else {
72 casted = dynCastToInt(p);
75 *casted = 1; // expected-warning {{Dereference of null pointer}}
78 void testMultipleStore(void *p) {
79 int *casted = 0;
80 casted = dynCastToInt(p);
81 *casted = 1;
82 #ifndef SUPPRESSED
83 // expected-warning@-2 {{Dereference of null pointer}}
84 #endif
87 // Test that div by zero does not get suppressed. This is a policy choice.
88 int retZero(void) {
89 return 0;
91 int triggerDivZero (void) {
92 int y = retZero();
93 return 5/y; // expected-warning {{Division by zero}}
96 // Treat a function-like macro similarly to an inlined function, so suppress
97 // warnings along paths resulting from inlined checks.
98 #define MACRO_WITH_CHECK(a) ( ((a) != 0) ? *a : 17)
99 void testInlineCheckInMacro(int *p) {
100 int i = MACRO_WITH_CHECK(p);
101 (void)i;
103 *p = 1; // no-warning
106 #define MACRO_WITH_NESTED_CHECK(a) ( { int j = MACRO_WITH_CHECK(a); j; } )
107 void testInlineCheckInNestedMacro(int *p) {
108 int i = MACRO_WITH_NESTED_CHECK(p);
109 (void)i;
111 *p = 1; // no-warning
114 #define NON_FUNCTION_MACRO_WITH_CHECK ( ((p) != 0) ? *p : 17)
115 void testNonFunctionMacro(int *p) {
116 int i = NON_FUNCTION_MACRO_WITH_CHECK ;
117 (void)i;
119 *p = 1; // no-warning
123 // This macro will dereference its argument if the argument is NULL.
124 #define MACRO_WITH_ERROR(a) ( ((a) != 0) ? 0 : *a)
125 void testErrorInMacro(int *p) {
126 int i = MACRO_WITH_ERROR(p); // expected-warning {{Dereference of null pointer (loaded from variable 'p')}}
127 (void)i;
130 // Here the check (the "if") is not in a macro, so we should still warn.
131 #define MACRO_IN_GUARD(a) (!(a))
132 void testMacroUsedAsGuard(int *p) {
133 if (MACRO_IN_GUARD(p))
134 *p = 1; // expected-warning {{Dereference of null pointer (loaded from variable 'p')}}
137 // When a nil case split is introduced in a macro and the macro is in a guard,
138 // we still shouldn't warn.
139 int isNull(int *p);
140 int isEqual(int *p, int *q);
141 #define ISNULL(ptr) ((ptr) == 0 || isNull(ptr))
142 #define ISEQUAL(a, b) ((int *)(a) == (int *)(b) || (ISNULL(a) && ISNULL(b)) || isEqual(a,b))
143 #define ISNOTEQUAL(a, b) (!ISEQUAL(a, b))
144 void testNestedDisjunctiveMacro(int *p, int *q) {
145 if (ISNOTEQUAL(p,q)) {
146 *p = 1; // no-warning
147 *q = 1; // no-warning
150 *p = 1; // no-warning
151 *q = 1; // no-warning
154 void testNestedDisjunctiveMacro2(int *p, int *q) {
155 if (ISEQUAL(p,q)) {
156 return;
159 *p = 1; // no-warning
160 *q = 1; // no-warning
165 // Here the check is entirely in non-macro code even though the code itself
166 // is a macro argument.
167 #define MACRO_DO_IT(a) (a)
168 void testErrorInArgument(int *p) {
169 int i = MACRO_DO_IT((p ? 0 : *p)); // expected-warning {{Dereference of null pointer (loaded from variable 'p')}}c
170 (void)i;
173 // No warning should be emitted if dereference is performed from a different
174 // macro.
175 #define MACRO_CHECK(a) if (a) {}
176 #define MACRO_DEREF(a) (*a)
177 int testDifferentMacro(int *p) {
178 MACRO_CHECK(p);
179 return MACRO_DEREF(p); // no-warning
182 // --------------------------
183 // "Suppression suppression"
184 // --------------------------
186 void testDynCastOrNullOfNull(void) {
187 // Don't suppress when one of the arguments is NULL.
188 int *casted = dynCastOrNull(0);
189 *casted = 1;
190 #if !SUPPRESSED || NULL_ARGS
191 // expected-warning@-2 {{Dereference of null pointer}}
192 #endif
195 void testDynCastOfNull(void) {
196 // Don't suppress when one of the arguments is NULL.
197 int *casted = dynCastToInt(0);
198 *casted = 1;
199 #if !SUPPRESSED || NULL_ARGS
200 // expected-warning@-2 {{Dereference of null pointer}}
201 #endif
204 int *lookUpInt(int unused) {
205 if (coin())
206 return 0;
207 static int x;
208 return &x;
211 void testZeroIsNotNull(void) {
212 // /Do/ suppress when the argument is 0 (an integer).
213 int *casted = lookUpInt(0);
214 *casted = 1;
215 #ifndef SUPPRESSED
216 // expected-warning@-2 {{Dereference of null pointer}}
217 #endif
220 void testTrackNull(void) {
221 // /Do/ suppress if the null argument came from another call returning null.
222 int *casted = dynCastOrNull(getNull());
223 *casted = 1;
224 #ifndef SUPPRESSED
225 // expected-warning@-2 {{Dereference of null pointer}}
226 #endif
229 void testTrackNullVariable(void) {
230 // /Do/ suppress if the null argument came from another call returning null.
231 int *ptr;
232 ptr = getNull();
233 int *casted = dynCastOrNull(ptr);
234 *casted = 1;
235 #ifndef SUPPRESSED
236 // expected-warning@-2 {{Dereference of null pointer}}
237 #endif
240 void inlinedIsDifferent(int inlined) {
241 int i;
243 // We were erroneously picking up the inner stack frame's initialization,
244 // even though the error occurs in the outer stack frame!
245 int *p = inlined ? &i : getNull();
247 if (!inlined)
248 inlinedIsDifferent(1);
250 *p = 1;
251 #ifndef SUPPRESSED
252 // expected-warning@-2 {{Dereference of null pointer}}
253 #endif
256 void testInlinedIsDifferent(void) {
257 // <rdar://problem/13787723>
258 inlinedIsDifferent(0);
262 // ---------------------------------------
263 // FALSE NEGATIVES (over-suppression)
264 // ---------------------------------------
266 void testNoArguments(void) {
267 // In this case the function has no branches, and MUST return null.
268 int *casted = getNull();
269 *casted = 1;
270 #ifndef SUPPRESSED
271 // expected-warning@-2 {{Dereference of null pointer}}
272 #endif
275 int *getNullIfNonNull(void *input) {
276 if (input)
277 return 0;
278 static int x;
279 return &x;
282 void testKnownPath(void *input) {
283 if (!input)
284 return;
286 // In this case we have a known value for the argument, and thus the path
287 // through the function doesn't ever split.
288 int *casted = getNullIfNonNull(input);
289 *casted = 1;
290 #ifndef SUPPRESSED
291 // expected-warning@-2 {{Dereference of null pointer}}
292 #endif
295 int *alwaysReturnNull(void *input) {
296 if (opaquePropertyCheck(input))
297 return 0;
298 return 0;
301 void testAlwaysReturnNull(void *input) {
302 // In this case all paths out of the function return 0, but they are all
303 // dominated by a branch whose condition we don't know!
304 int *casted = alwaysReturnNull(input);
305 *casted = 1;
306 #ifndef SUPPRESSED
307 // expected-warning@-2 {{Dereference of null pointer}}
308 #endif
311 int derefArg(int *p) {
312 return *p;
313 #ifndef SUPPRESSED
314 // expected-warning@-2 {{Dereference of null pointer}}
315 #endif
317 void ternaryArg(char cond) {
318 static int x;
319 derefArg(cond ? &x : getNull());
322 int derefArgCast(char *p) {
323 return *p;
324 #ifndef SUPPRESSED
325 // expected-warning@-2 {{Dereference of null pointer}}
326 #endif
328 void ternaryArgCast(char cond) {
329 static int x;
330 derefArgCast((char*)((unsigned)cond ? &x : getNull()));
333 int derefAssignment(int *p) {
334 return *p;
335 #ifndef SUPPRESSED
336 // expected-warning@-2 {{Dereference of null pointer}}
337 #endif
340 void ternaryAssignment(char cond) {
341 static int x;
342 int *p = cond ? getNull() : getPtr();
343 derefAssignment(p);
346 int *retNull(char cond) {
347 static int x;
348 return cond ? &x : getNull();
350 int ternaryRetNull(char cond) {
351 int *p = retNull(cond);
352 return *p;
353 #ifndef SUPPRESSED
354 // expected-warning@-2 {{Dereference of null pointer}}
355 #endif
358 // Test suppression of nested conditional operators.
359 int testConditionalOperatorSuppress(int x) {
360 return *(x ? getNull() : getPtr());
361 #ifndef SUPPRESSED
362 // expected-warning@-2 {{Dereference of null pointer}}
363 #endif
365 int testNestedConditionalOperatorSuppress(int x) {
366 return *(x ? (x ? getNull() : getPtr()) : getPtr());
367 #ifndef SUPPRESSED
368 // expected-warning@-2 {{Dereference of null pointer}}
369 #endif
371 int testConditionalOperator(int x) {
372 return *(x ? 0 : getPtr()); // expected-warning {{Dereference of null pointer}}
374 int testNestedConditionalOperator(int x) {
375 return *(x ? (x ? 0 : getPtr()) : getPtr()); // expected-warning {{Dereference of null pointer}}
378 int testConditionalOperatorSuppressFloatCond(float x) {
379 return *(x ? getNull() : getPtr());
380 #ifndef SUPPRESSED
381 // expected-warning@-2 {{Dereference of null pointer}}
382 #endif