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 
3 void clang_analyzer_eval(int);
4 
5 // test to see if nullptr is detected as a null pointer
6 void 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
13 void 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
23 void 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
37 void 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 
46 int 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 
53 void 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 
59 void 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 
65 typedef __INTPTR_TYPE__ intptr_t;
66 void 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 
72 void 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 
82 int 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 
95 int 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 
106 typedef decltype(nullptr) nullptr_t;
107 void testMaterializeTemporaryExprWithNullPtr() {
108   // Create MaterializeTemporaryExpr with a nullptr inside.
109   const nullptr_t &r = nullptr;
110 }
111 
112 int getSymbol();
113 
114 struct X {
115   virtual void f() {}
116 };
117 
118 void 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 
123 struct Type {
124   decltype(nullptr) x;
125 };
126 
127 void 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 
152 void 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 
160 decltype(nullptr) returnsNullPtrType();
161 void 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)))
167 class AS1 {
168 public:
169   int x;
170   ~AS1() {
171     int AS_ATTRIBUTE *x = 0;
172     *x = 3; // no-warning
173   }
174 };
175 void test_address_space_field_access() {
176   AS1 AS_ATTRIBUTE *pa = 0;
177   pa->x = 0; // no-warning
178 }
179 void test_address_space_bind() {
180   AS1 AS_ATTRIBUTE *pa = 0;
181   AS1 AS_ATTRIBUTE &r = *pa;
182   r.x = 0; // no-warning
183 }
184