Clang Project

clang_source_code/test/Analysis/nullptr.cpp
1// RUN: %clang_analyze_cc1 -std=c++11 -Wno-conversion-null -analyzer-checker=core,debug.ExprInspection -analyzer-store region -analyzer-output=text -verify %s
2
3void clang_analyzer_eval(int);
4
5// test to see if nullptr is detected as a null pointer
6void foo1(void) {
7  char  *np = nullptr; // expected-note{{'np' initialized to a null pointer value}}
8  *np = 0;  // expected-warning{{Dereference of null pointer}}
9            // expected-note@-1{{Dereference of null pointer}}
10}
11
12// check if comparing nullptr to nullptr is detected properly
13void foo2(void) {
14  char *np1 = nullptr;
15  char *np2 = np1;
16  char c;
17  if (np1 == np2)
18    np1 = &c;
19  *np1 = 0;  // no-warning
20}
21
22// invoving a nullptr in a more complex operation should be cause a warning
23void foo3(void) {
24  struct foo {
25    int a, f;
26  };
27  char *np = nullptr; // expected-note{{'np' initialized to a null pointer value}}
28  // casting a nullptr to anything should be caught eventually
29  int *ip = &(((struct foo *)np)->f); // expected-note{{'ip' initialized to a null pointer value}}
30  *ip = 0;  // expected-warning{{Dereference of null pointer}}
31            // expected-note@-1{{Dereference of null pointer}}
32  // should be error here too, but analysis gets stopped
33//  *np = 0;
34}
35
36// nullptr is implemented as a zero integer value, so should be able to compare
37void foo4(void) {
38  char *np = nullptr;
39  if (np != 0)
40    *np = 0;  // no-warning
41  char  *cp = 0;
42  if (np != cp)
43    *np = 0;  // no-warning
44}
45
46int pr10372(void *& x) {
47  // GNU null is a pointer-sized integer, not a pointer.
48  x = __null;
49  // This used to crash.
50  return __null;
51}
52
53void zoo1() {
54  char **p = 0; // expected-note{{'p' initialized to a null pointer value}}
55  delete *(p + 0); // expected-warning{{Dereference of null pointer}}
56                   // expected-note@-1{{Dereference of null pointer}}
57}
58
59void zoo1backwards() {
60  char **p = 0; // expected-note{{'p' initialized to a null pointer value}}
61  delete *(0 + p); // expected-warning{{Dereference of null pointer}}
62                   // expected-note@-1{{Dereference of null pointer}}
63}
64
65typedef __INTPTR_TYPE__ intptr_t;
66void zoo1multiply() {
67  char **p = 0; // FIXME-should-be-note:{{'p' initialized to a null pointer value}}
68  delete *((char **)((intptr_t)p * 2)); // expected-warning{{Dereference of null pointer}}
69                   // expected-note@-1{{Dereference of null pointer}}
70}
71
72void zoo2() {
73  int **a = 0;
74  int **b = 0; // expected-note{{'b' initialized to a null pointer value}}
75  asm ("nop"
76      :"=r"(*a)
77      :"0"(*b) // expected-warning{{Dereference of null pointer}}
78               // expected-note@-1{{Dereference of null pointer}}
79      );
80}
81
82int exprWithCleanups() {
83  struct S {
84    S(int a):a(a){}
85    ~S() {}
86
87    int a;
88  };
89
90  int *x = 0; // expected-note{{'x' initialized to a null pointer value}}
91  return S(*x).a; // expected-warning{{Dereference of null pointer}}
92                  // expected-note@-1{{Dereference of null pointer}}
93}
94
95int materializeTempExpr() {
96  int *n = 0; // expected-note{{'n' initialized to a null pointer value}}
97  struct S {
98    int a;
99    S(int i): a(i) {}
100  };
101  const S &s = S(*n); // expected-warning{{Dereference of null pointer}}
102                      // expected-note@-1{{Dereference of null pointer}}
103  return s.a;
104}
105
106typedef decltype(nullptr) nullptr_t;
107void testMaterializeTemporaryExprWithNullPtr() {
108  // Create MaterializeTemporaryExpr with a nullptr inside.
109  const nullptr_t &r = nullptr;
110}
111
112int getSymbol();
113
114struct X {
115  virtual void f() {}
116};
117
118void invokeF(X* x) {
119  x->f(); // expected-warning{{Called C++ object pointer is null}}
120          // expected-note@-1{{Called C++ object pointer is null}}
121}
122
123struct Type {
124  decltype(nullptr) x;
125};
126
127void shouldNotCrash() {
128  decltype(nullptr) p; // expected-note{{'p' declared without an initial value}}
129  if (getSymbol()) // expected-note   {{Assuming the condition is false}}
130                   // expected-note@-1{{Taking false branch}}
131                   // expected-note@-2{{Assuming the condition is false}}
132                   // expected-note@-3{{Taking false branch}}
133                   // expected-note@-4{{Assuming the condition is true}}
134                   // expected-note@-5{{Taking true branch}}
135    invokeF(p); // expected-warning{{1st function call argument is an uninitialized value}}
136                // expected-note@-1{{1st function call argument is an uninitialized value}}
137  if (getSymbol()) // expected-note   {{Assuming the condition is false}}
138                   // expected-note@-1{{Taking false branch}}
139                   // expected-note@-2{{Assuming the condition is true}}
140                   // expected-note@-3{{Taking true branch}}
141    invokeF(nullptr); // expected-note   {{Calling 'invokeF'}}
142                      // expected-note@-1{{Passing null pointer value via 1st parameter 'x'}}
143  if (getSymbol()) {  // expected-note  {{Assuming the condition is true}}
144                      // expected-note@-1{{Taking true branch}}
145    X *xx = Type().x; // expected-note   {{Null pointer value stored to field 'x'}}
146                      // expected-note@-1{{'xx' initialized to a null pointer value}}
147    xx->f(); // expected-warning{{Called C++ object pointer is null}}
148            // expected-note@-1{{Called C++ object pointer is null}}
149  }
150}
151
152void f(decltype(nullptr) p) {
153  int *q = nullptr;
154  clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
155                               // expected-note@-1{{TRUE}}
156  clang_analyzer_eval(q == 0); // expected-warning{{TRUE}}
157                               // expected-note@-1{{TRUE}}
158}
159
160decltype(nullptr) returnsNullPtrType();
161void fromReturnType() {
162  ((X *)returnsNullPtrType())->f(); // expected-warning{{Called C++ object pointer is null}}
163                                    // expected-note@-1{{Called C++ object pointer is null}}
164}
165
166#define AS_ATTRIBUTE __attribute__((address_space(256)))
167class AS1 {
168public:
169  int x;
170  ~AS1() {
171    int AS_ATTRIBUTE *x = 0;
172    *x = 3; // no-warning
173  }
174};
175void test_address_space_field_access() {
176  AS1 AS_ATTRIBUTE *pa = 0;
177  pa->x = 0; // no-warning
178}
179void test_address_space_bind() {
180  AS1 AS_ATTRIBUTE *pa = 0;
181  AS1 AS_ATTRIBUTE &r = *pa;
182  r.x = 0; // no-warning
183}
184