false-positive-suppression.c revision b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1
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 %s
3
4int opaquePropertyCheck(void *object);
5int coin();
6
7int *dynCastToInt(void *ptr) {
8  if (opaquePropertyCheck(ptr))
9    return (int *)ptr;
10  return 0;
11}
12
13int *dynCastOrNull(void *ptr) {
14  if (!ptr)
15    return 0;
16  if (opaquePropertyCheck(ptr))
17    return (int *)ptr;
18  return 0;
19}
20
21
22void testDynCast(void *p) {
23  int *casted = dynCastToInt(p);
24  *casted = 1;
25#ifndef SUPPRESSED
26  // expected-warning@-2 {{Dereference of null pointer}}
27#endif
28}
29
30void testDynCastOrNull(void *p) {
31  int *casted = dynCastOrNull(p);
32  *casted = 1;
33#ifndef SUPPRESSED
34  // expected-warning@-2 {{Dereference of null pointer}}
35#endif
36}
37
38
39void testBranch(void *p) {
40  int *casted;
41
42  // Although the report will be suppressed on one branch, it should still be
43  // valid on the other.
44  if (coin()) {
45    casted = dynCastToInt(p);
46  } else {
47    if (p)
48      return;
49    casted = (int *)p;
50  }
51
52  *casted = 1; // expected-warning {{Dereference of null pointer}}
53}
54
55void testBranchReversed(void *p) {
56  int *casted;
57
58  // Although the report will be suppressed on one branch, it should still be
59  // valid on the other.
60  if (coin()) {
61    if (p)
62      return;
63    casted = (int *)p;
64  } else {
65    casted = dynCastToInt(p);
66  }
67
68  *casted = 1; // expected-warning {{Dereference of null pointer}}
69}
70
71
72// ---------------------------------------
73// FALSE NEGATIVES (over-suppression)
74// ---------------------------------------
75
76void testDynCastOrNullOfNull() {
77  // In this case we have a known value for the argument, and thus the path
78  // through the function doesn't ever split.
79  int *casted = dynCastOrNull(0);
80  *casted = 1;
81#ifndef SUPPRESSED
82  // expected-warning@-2 {{Dereference of null pointer}}
83#endif
84}
85
86void testDynCastOfNull() {
87  // In this case all paths out of the function return 0, but they are all
88  // dominated by a branch whose condition we don't know!
89  int *casted = dynCastToInt(0);
90  *casted = 1;
91#ifndef SUPPRESSED
92  // expected-warning@-2 {{Dereference of null pointer}}
93#endif
94}
95
96