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
);
14 int *dynCastToInt(void *ptr
) {
15 if (opaquePropertyCheck(ptr
))
20 int *dynCastOrNull(void *ptr
) {
23 if (opaquePropertyCheck(ptr
))
29 void testDynCast(void *p
) {
30 int *casted
= dynCastToInt(p
);
33 // expected-warning@-2 {{Dereference of null pointer}}
37 void testDynCastOrNull(void *p
) {
38 int *casted
= dynCastOrNull(p
);
41 // expected-warning@-2 {{Dereference of null pointer}}
46 void testBranch(void *p
) {
49 // Although the report will be suppressed on one branch, it should still be
50 // valid on the other.
52 casted
= dynCastToInt(p
);
59 *casted
= 1; // expected-warning {{Dereference of null pointer}}
62 void testBranchReversed(void *p
) {
65 // Although the report will be suppressed on one branch, it should still be
66 // valid on the other.
72 casted
= dynCastToInt(p
);
75 *casted
= 1; // expected-warning {{Dereference of null pointer}}
78 void testMultipleStore(void *p
) {
80 casted
= dynCastToInt(p
);
83 // expected-warning@-2 {{Dereference of null pointer}}
87 // Test that div by zero does not get suppressed. This is a policy choice.
91 int triggerDivZero (void) {
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
);
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
);
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
;
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')}}
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.
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
) {
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
173 // No warning should be emitted if dereference is performed from a different
175 #define MACRO_CHECK(a) if (a) {}
176 #define MACRO_DEREF(a) (*a)
177 int testDifferentMacro(int *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);
190 #if !SUPPRESSED || NULL_ARGS
191 // expected-warning@-2 {{Dereference of null pointer}}
195 void testDynCastOfNull(void) {
196 // Don't suppress when one of the arguments is NULL.
197 int *casted
= dynCastToInt(0);
199 #if !SUPPRESSED || NULL_ARGS
200 // expected-warning@-2 {{Dereference of null pointer}}
204 int *lookUpInt(int unused
) {
211 void testZeroIsNotNull(void) {
212 // /Do/ suppress when the argument is 0 (an integer).
213 int *casted
= lookUpInt(0);
216 // expected-warning@-2 {{Dereference of null pointer}}
220 void testTrackNull(void) {
221 // /Do/ suppress if the null argument came from another call returning null.
222 int *casted
= dynCastOrNull(getNull());
225 // expected-warning@-2 {{Dereference of null pointer}}
229 void testTrackNullVariable(void) {
230 // /Do/ suppress if the null argument came from another call returning null.
233 int *casted
= dynCastOrNull(ptr
);
236 // expected-warning@-2 {{Dereference of null pointer}}
240 void inlinedIsDifferent(int inlined
) {
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();
248 inlinedIsDifferent(1);
252 // expected-warning@-2 {{Dereference of null pointer}}
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();
271 // expected-warning@-2 {{Dereference of null pointer}}
275 int *getNullIfNonNull(void *input
) {
282 void testKnownPath(void *input
) {
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
);
291 // expected-warning@-2 {{Dereference of null pointer}}
295 int *alwaysReturnNull(void *input
) {
296 if (opaquePropertyCheck(input
))
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
);
307 // expected-warning@-2 {{Dereference of null pointer}}
311 int derefArg(int *p
) {
314 // expected-warning@-2 {{Dereference of null pointer}}
317 void ternaryArg(char cond
) {
319 derefArg(cond
? &x
: getNull());
322 int derefArgCast(char *p
) {
325 // expected-warning@-2 {{Dereference of null pointer}}
328 void ternaryArgCast(char cond
) {
330 derefArgCast((char*)((unsigned)cond
? &x
: getNull()));
333 int derefAssignment(int *p
) {
336 // expected-warning@-2 {{Dereference of null pointer}}
340 void ternaryAssignment(char cond
) {
342 int *p
= cond
? getNull() : getPtr();
346 int *retNull(char cond
) {
348 return cond
? &x
: getNull();
350 int ternaryRetNull(char cond
) {
351 int *p
= retNull(cond
);
354 // expected-warning@-2 {{Dereference of null pointer}}
358 // Test suppression of nested conditional operators.
359 int testConditionalOperatorSuppress(int x
) {
360 return *(x
? getNull() : getPtr());
362 // expected-warning@-2 {{Dereference of null pointer}}
365 int testNestedConditionalOperatorSuppress(int x
) {
366 return *(x
? (x
? getNull() : getPtr()) : getPtr());
368 // expected-warning@-2 {{Dereference of null pointer}}
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());
381 // expected-warning@-2 {{Dereference of null pointer}}