false-positive-suppression.c revision 702077f14100f2d7acdb12ad49b53e64efc37d72
1b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config suppress-null-return-paths=false -verify %s
26a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -DSUPPRESSED=1 %s
36a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config avoid-suppressing-null-argument-paths=true -DSUPPRESSED=1 -DNULL_ARGS=1 -verify %s
4b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose
5b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Roseint opaquePropertyCheck(void *object);
6b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Roseint coin();
7b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose
86a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Roseint *getNull() {
96a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  return 0;
106a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose}
116a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose
12c1bef5671e682de5a573c7c6b66871b36de0ec61Anna Zaksint* getPtr();
13c1bef5671e682de5a573c7c6b66871b36de0ec61Anna Zaks
14b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Roseint *dynCastToInt(void *ptr) {
15b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  if (opaquePropertyCheck(ptr))
16b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose    return (int *)ptr;
17b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  return 0;
18b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose}
19b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose
20b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Roseint *dynCastOrNull(void *ptr) {
21b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  if (!ptr)
22b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose    return 0;
23b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  if (opaquePropertyCheck(ptr))
24b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose    return (int *)ptr;
25b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  return 0;
26b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose}
27b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose
28b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose
29b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rosevoid testDynCast(void *p) {
30b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  int *casted = dynCastToInt(p);
31b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  *casted = 1;
32b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose#ifndef SUPPRESSED
33b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  // expected-warning@-2 {{Dereference of null pointer}}
34b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose#endif
35b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose}
36b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose
37b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rosevoid testDynCastOrNull(void *p) {
38b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  int *casted = dynCastOrNull(p);
39b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  *casted = 1;
40b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose#ifndef SUPPRESSED
41b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  // expected-warning@-2 {{Dereference of null pointer}}
42b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose#endif
43b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose}
44b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose
45b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose
46b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rosevoid testBranch(void *p) {
47b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  int *casted;
48b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose
49b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  // Although the report will be suppressed on one branch, it should still be
50b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  // valid on the other.
51b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  if (coin()) {
52b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose    casted = dynCastToInt(p);
53b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  } else {
54b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose    if (p)
55b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose      return;
56b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose    casted = (int *)p;
57b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  }
58b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose
59b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  *casted = 1; // expected-warning {{Dereference of null pointer}}
60b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose}
61b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose
62b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rosevoid testBranchReversed(void *p) {
63b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  int *casted;
64b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose
65b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  // Although the report will be suppressed on one branch, it should still be
66b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  // valid on the other.
67b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  if (coin()) {
68b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose    if (p)
69b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose      return;
70b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose    casted = (int *)p;
71b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  } else {
72b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose    casted = dynCastToInt(p);
73b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  }
74b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose
75b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  *casted = 1; // expected-warning {{Dereference of null pointer}}
76b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose}
77b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose
786f4160828db75f36b22a204da202723c592644f3Jordan Rosevoid testMultipleStore(void *p) {
796f4160828db75f36b22a204da202723c592644f3Jordan Rose  int *casted = 0;
806f4160828db75f36b22a204da202723c592644f3Jordan Rose  casted = dynCastToInt(p);
816f4160828db75f36b22a204da202723c592644f3Jordan Rose  *casted = 1;
826f4160828db75f36b22a204da202723c592644f3Jordan Rose#ifndef SUPPRESSED
836f4160828db75f36b22a204da202723c592644f3Jordan Rose  // expected-warning@-2 {{Dereference of null pointer}}
846f4160828db75f36b22a204da202723c592644f3Jordan Rose#endif
856f4160828db75f36b22a204da202723c592644f3Jordan Rose}
866f4160828db75f36b22a204da202723c592644f3Jordan Rose
87b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose
886a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose// --------------------------
896a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose// "Suppression suppression"
906a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose// --------------------------
916a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose
926a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rosevoid testDynCastOrNullOfNull() {
936a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  // Don't suppress when one of the arguments is NULL.
946a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  int *casted = dynCastOrNull(0);
956a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  *casted = 1;
966a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose#if !SUPPRESSED || NULL_ARGS
976a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  // expected-warning@-2 {{Dereference of null pointer}}
986a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose#endif
996a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose}
1006a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose
1016a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rosevoid testDynCastOfNull() {
1026a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  // Don't suppress when one of the arguments is NULL.
1036a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  int *casted = dynCastToInt(0);
1046a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  *casted = 1;
1056a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose#if !SUPPRESSED || NULL_ARGS
1066a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  // expected-warning@-2 {{Dereference of null pointer}}
1076a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose#endif
1086a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose}
1096a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose
1106a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Roseint *lookUpInt(int unused) {
1116a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  if (coin())
1126a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose    return 0;
1136a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  static int x;
1146a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  return &x;
1156a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose}
1166a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose
1176a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rosevoid testZeroIsNotNull() {
1186a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  // /Do/ suppress when the argument is 0 (an integer).
1196a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  int *casted = lookUpInt(0);
1206a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  *casted = 1;
1216a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose#ifndef SUPPRESSED
1226a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  // expected-warning@-2 {{Dereference of null pointer}}
1236a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose#endif
1246a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose}
1256a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose
1266a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rosevoid testTrackNull() {
1276a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  // /Do/ suppress if the null argument came from another call returning null.
1286a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  int *casted = dynCastOrNull(getNull());
1296a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  *casted = 1;
1306a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose#ifndef SUPPRESSED
1316a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  // expected-warning@-2 {{Dereference of null pointer}}
1326a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose#endif
1336a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose}
1346a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose
1356a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rosevoid testTrackNullVariable() {
1366a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  // /Do/ suppress if the null argument came from another call returning null.
1376a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  int *ptr;
1386a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  ptr = getNull();
1396a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  int *casted = dynCastOrNull(ptr);
1406a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  *casted = 1;
1416a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose#ifndef SUPPRESSED
1426a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  // expected-warning@-2 {{Dereference of null pointer}}
1436a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose#endif
1446a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose}
1456a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose
1466a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose
147b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose// ---------------------------------------
148b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose// FALSE NEGATIVES (over-suppression)
149b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose// ---------------------------------------
150b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose
1516a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rosevoid testNoArguments() {
1526a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  // In this case the function has no branches, and MUST return null.
1536a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  int *casted = getNull();
1546a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  *casted = 1;
1556a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose#ifndef SUPPRESSED
1566a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  // expected-warning@-2 {{Dereference of null pointer}}
1576a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose#endif
1586a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose}
1596a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose
1606a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Roseint *getNullIfNonNull(void *input) {
1616a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  if (input)
1626a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose    return 0;
1636a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  static int x;
1646a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  return &x;
1656a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose}
1666a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose
1676a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rosevoid testKnownPath(void *input) {
1686a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  if (!input)
1696a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose    return;
1706a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose
171b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  // In this case we have a known value for the argument, and thus the path
172b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  // through the function doesn't ever split.
1736a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  int *casted = getNullIfNonNull(input);
174b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  *casted = 1;
175b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose#ifndef SUPPRESSED
176b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  // expected-warning@-2 {{Dereference of null pointer}}
177b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose#endif
178b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose}
179b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose
1806a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Roseint *alwaysReturnNull(void *input) {
1816a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  if (opaquePropertyCheck(input))
1826a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose    return 0;
1836a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  return 0;
1846a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose}
1856a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose
1866a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rosevoid testAlwaysReturnNull(void *input) {
187b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  // In this case all paths out of the function return 0, but they are all
188b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  // dominated by a branch whose condition we don't know!
1896a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  int *casted = alwaysReturnNull(input);
190b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  *casted = 1;
191b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose#ifndef SUPPRESSED
192b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  // expected-warning@-2 {{Dereference of null pointer}}
193b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose#endif
194b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose}
195b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose
196dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaksint derefArg(int *p) {
197dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaks	return *p;
198dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaks#ifndef SUPPRESSED
199dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaks  // expected-warning@-2 {{Dereference of null pointer}}
200dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaks#endif
201dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaks}
202dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaksvoid ternaryArg(char cond) {
203dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaks	static int x;
204dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaks	derefArg(cond ? &x : getNull());
205dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaks}
206dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaks
207f510f5cd57fa9b7ea6f6e103c65c0df95a55d986Anna Zaksint derefArgCast(char *p) {
208f510f5cd57fa9b7ea6f6e103c65c0df95a55d986Anna Zaks	return *p;
209f510f5cd57fa9b7ea6f6e103c65c0df95a55d986Anna Zaks#ifndef SUPPRESSED
210f510f5cd57fa9b7ea6f6e103c65c0df95a55d986Anna Zaks  // expected-warning@-2 {{Dereference of null pointer}}
211f510f5cd57fa9b7ea6f6e103c65c0df95a55d986Anna Zaks#endif
212f510f5cd57fa9b7ea6f6e103c65c0df95a55d986Anna Zaks}
213f510f5cd57fa9b7ea6f6e103c65c0df95a55d986Anna Zaksvoid ternaryArgCast(char cond) {
214f510f5cd57fa9b7ea6f6e103c65c0df95a55d986Anna Zaks	static int x;
215f510f5cd57fa9b7ea6f6e103c65c0df95a55d986Anna Zaks	derefArgCast((char*)((unsigned)cond ? &x : getNull()));
216f510f5cd57fa9b7ea6f6e103c65c0df95a55d986Anna Zaks}
217f510f5cd57fa9b7ea6f6e103c65c0df95a55d986Anna Zaks
218dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaksint derefAssignment(int *p) {
219dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaks	return *p;
220dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaks#ifndef SUPPRESSED
221dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaks  // expected-warning@-2 {{Dereference of null pointer}}
222dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaks#endif
223dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaks}
224c1bef5671e682de5a573c7c6b66871b36de0ec61Anna Zaks
225dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaksvoid ternaryAssignment(char cond) {
226dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaks  static int x;
227c1bef5671e682de5a573c7c6b66871b36de0ec61Anna Zaks  int *p = cond ? getNull() : getPtr();
228dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaks  derefAssignment(p);
229dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaks}
230dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaks
231dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaksint *retNull(char cond) {
232dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaks  static int x;
233dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaks  return cond ? &x : getNull();
234dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaks}
235dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaksint ternaryRetNull(char cond) {
236dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaks  int *p = retNull(cond);
237dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaks  return *p;
238dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaks#ifndef SUPPRESSED
239dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaks  // expected-warning@-2 {{Dereference of null pointer}}
240dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaks#endif
241dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaks}
242dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaks
243cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks// Test suppression of nested conditional operators.
244cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaksint testConditionalOperatorSuppress(int x) {
245cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks  return *(x ? getNull() : getPtr());
246cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks#ifndef SUPPRESSED
247cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks  // expected-warning@-2 {{Dereference of null pointer}}
248cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks#endif
249cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks}
250cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaksint testNestedConditionalOperatorSuppress(int x) {
251cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks  return *(x ? (x ? getNull() : getPtr()) : getPtr());
252cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks#ifndef SUPPRESSED
253cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks  // expected-warning@-2 {{Dereference of null pointer}}
254cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks#endif
255cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks}
256cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaksint testConditionalOperator(int x) {
257cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks  return *(x ? 0 : getPtr()); // expected-warning {{Dereference of null pointer}}
258cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks}
259cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaksint testNestedConditionalOperator(int x) {
260cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks  return *(x ? (x ? 0 : getPtr()) : getPtr()); // expected-warning {{Dereference of null pointer}}
261cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks}
262cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks
263cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaksint testConditionalOperatorSuppressFloatCond(float x) {
264702077f14100f2d7acdb12ad49b53e64efc37d72Anna Zaks  return *(x ? getNull() : getPtr());
265702077f14100f2d7acdb12ad49b53e64efc37d72Anna Zaks#ifndef SUPPRESSED
266702077f14100f2d7acdb12ad49b53e64efc37d72Anna Zaks  // expected-warning@-2 {{Dereference of null pointer}}
267702077f14100f2d7acdb12ad49b53e64efc37d72Anna Zaks#endif
268cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks}
269dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaks
270