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 | |