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
foo1(void)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
foo2(void)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
foo3(void)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
foo4(void)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 
pr10372(void * & x)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 
zoo1()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 
zoo1backwards()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;
zoo1multiply()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 
zoo2()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 
exprWithCleanups()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 
materializeTempExpr()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;
testMaterializeTemporaryExprWithNullPtr()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 {
fX115   virtual void f() {}
116 };
117 
invokeF(X * x)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 
shouldNotCrash()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 true}}
132                    // expected-note@-3{{Taking true branch}}
133     invokeF(p);    // expected-note   {{Calling 'invokeF'}}
134                    // expected-note@-1{{Passing null pointer value via 1st parameter 'x'}}
135   if (getSymbol()) {  // expected-note  {{Assuming the condition is true}}
136                       // expected-note@-1{{Taking true branch}}
137     X *xx = Type().x; // expected-note   {{Null pointer value stored to field 'x'}}
138                       // expected-note@-1{{'xx' initialized to a null pointer value}}
139     xx->f(); // expected-warning{{Called C++ object pointer is null}}
140             // expected-note@-1{{Called C++ object pointer is null}}
141   }
142 }
143 
f(decltype(nullptr)p)144 void f(decltype(nullptr) p) {
145   int *q = nullptr;
146   clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
147                                // expected-note@-1{{TRUE}}
148   clang_analyzer_eval(q == 0); // expected-warning{{TRUE}}
149                                // expected-note@-1{{TRUE}}
150 }
151 
152 decltype(nullptr) returnsNullPtrType();
fromReturnType()153 void fromReturnType() {
154   ((X *)returnsNullPtrType())->f(); // expected-warning{{Called C++ object pointer is null}}
155                                     // expected-note@-1{{Called C++ object pointer is null}}
156 }
157 
158 #define AS_ATTRIBUTE __attribute__((address_space(256)))
159 class AS1 {
160 public:
161   int x;
~AS1()162   ~AS1() {
163     int AS_ATTRIBUTE *x = 0;
164     *x = 3; // no-warning
165   }
166 };
test_address_space_field_access()167 void test_address_space_field_access() {
168   AS1 AS_ATTRIBUTE *pa = 0;
169   pa->x = 0; // no-warning
170 }
test_address_space_bind()171 void test_address_space_bind() {
172   AS1 AS_ATTRIBUTE *pa = 0;
173   AS1 AS_ATTRIBUTE &r = *pa;
174   r.x = 0; // no-warning
175 }
176