1 // RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config suppress-null-return-paths=false -verify %s
2 // RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -DSUPPRESSED=1 %s
3 // RUN: %clang_cc1 -analyze -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 () {
93 return 5/y; // expected-warning {{Division by zero}}
96 // --------------------------
97 // "Suppression suppression"
98 // --------------------------
100 void testDynCastOrNullOfNull() {
101 // Don't suppress when one of the arguments is NULL.
102 int *casted = dynCastOrNull(0);
104 #if !SUPPRESSED || NULL_ARGS
105 // expected-warning@-2 {{Dereference of null pointer}}
109 void testDynCastOfNull() {
110 // Don't suppress when one of the arguments is NULL.
111 int *casted = dynCastToInt(0);
113 #if !SUPPRESSED || NULL_ARGS
114 // expected-warning@-2 {{Dereference of null pointer}}
118 int *lookUpInt(int unused) {
125 void testZeroIsNotNull() {
126 // /Do/ suppress when the argument is 0 (an integer).
127 int *casted = lookUpInt(0);
130 // expected-warning@-2 {{Dereference of null pointer}}
134 void testTrackNull() {
135 // /Do/ suppress if the null argument came from another call returning null.
136 int *casted = dynCastOrNull(getNull());
139 // expected-warning@-2 {{Dereference of null pointer}}
143 void testTrackNullVariable() {
144 // /Do/ suppress if the null argument came from another call returning null.
147 int *casted = dynCastOrNull(ptr);
150 // expected-warning@-2 {{Dereference of null pointer}}
154 void inlinedIsDifferent(int inlined) {
157 // We were erroneously picking up the inner stack frame's initialization,
158 // even though the error occurs in the outer stack frame!
159 int *p = inlined ? &i : getNull();
162 inlinedIsDifferent(1);
166 // expected-warning@-2 {{Dereference of null pointer}}
170 void testInlinedIsDifferent() {
171 // <rdar://problem/13787723>
172 inlinedIsDifferent(0);
176 // ---------------------------------------
177 // FALSE NEGATIVES (over-suppression)
178 // ---------------------------------------
180 void testNoArguments() {
181 // In this case the function has no branches, and MUST return null.
182 int *casted = getNull();
185 // expected-warning@-2 {{Dereference of null pointer}}
189 int *getNullIfNonNull(void *input) {
196 void testKnownPath(void *input) {
200 // In this case we have a known value for the argument, and thus the path
201 // through the function doesn't ever split.
202 int *casted = getNullIfNonNull(input);
205 // expected-warning@-2 {{Dereference of null pointer}}
209 int *alwaysReturnNull(void *input) {
210 if (opaquePropertyCheck(input))
215 void testAlwaysReturnNull(void *input) {
216 // In this case all paths out of the function return 0, but they are all
217 // dominated by a branch whose condition we don't know!
218 int *casted = alwaysReturnNull(input);
221 // expected-warning@-2 {{Dereference of null pointer}}
225 int derefArg(int *p) {
228 // expected-warning@-2 {{Dereference of null pointer}}
231 void ternaryArg(char cond) {
233 derefArg(cond ? &x : getNull());
236 int derefArgCast(char *p) {
239 // expected-warning@-2 {{Dereference of null pointer}}
242 void ternaryArgCast(char cond) {
244 derefArgCast((char*)((unsigned)cond ? &x : getNull()));
247 int derefAssignment(int *p) {
250 // expected-warning@-2 {{Dereference of null pointer}}
254 void ternaryAssignment(char cond) {
256 int *p = cond ? getNull() : getPtr();
260 int *retNull(char cond) {
262 return cond ? &x : getNull();
264 int ternaryRetNull(char cond) {
265 int *p = retNull(cond);
268 // expected-warning@-2 {{Dereference of null pointer}}
272 // Test suppression of nested conditional operators.
273 int testConditionalOperatorSuppress(int x) {
274 return *(x ? getNull() : getPtr());
276 // expected-warning@-2 {{Dereference of null pointer}}
279 int testNestedConditionalOperatorSuppress(int x) {
280 return *(x ? (x ? getNull() : getPtr()) : getPtr());
282 // expected-warning@-2 {{Dereference of null pointer}}
285 int testConditionalOperator(int x) {
286 return *(x ? 0 : getPtr()); // expected-warning {{Dereference of null pointer}}
288 int testNestedConditionalOperator(int x) {
289 return *(x ? (x ? 0 : getPtr()) : getPtr()); // expected-warning {{Dereference of null pointer}}
292 int testConditionalOperatorSuppressFloatCond(float x) {
293 return *(x ? getNull() : getPtr());
295 // expected-warning@-2 {{Dereference of null pointer}}