1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-store region -std=c++11 -verify -analyzer-config eagerly-assume=false %s
2 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-store region -std=c++11 -DTEST_INLINABLE_ALLOCATORS -verify -analyzer-config eagerly-assume=false %s
3 #include "Inputs/system-header-simulator-cxx.h"
4 
5 void clang_analyzer_eval(bool);
6 
7 typedef __typeof__(sizeof(int)) size_t;
8 extern "C" void *malloc(size_t);
9 extern "C" void free(void *);
10 
11 int someGlobal;
12 
13 class SomeClass {
14 public:
15   void f(int *p);
16 };
17 
18 void testImplicitlyDeclaredGlobalNew() {
19   if (someGlobal != 0)
20     return;
21 
22   // This used to crash because the global operator new is being implicitly
23   // declared and it does not have a valid source location. (PR13090)
24   void *x = ::operator new(0);
25   ::operator delete(x);
26 
27   // Check that the new/delete did not invalidate someGlobal;
28   clang_analyzer_eval(someGlobal == 0); // expected-warning{{TRUE}}
29 }
30 
31 void *testPlacementNew() {
32   int *x = (int *)malloc(sizeof(int));
33   *x = 1;
34   clang_analyzer_eval(*x == 1); // expected-warning{{TRUE}};
35 
36   void *y = new (x) int;
37   clang_analyzer_eval(x == y); // expected-warning{{TRUE}};
38   clang_analyzer_eval(*x == 1); // expected-warning{{TRUE}};
39 
40   return y;
41 }
42 
43 void *operator new(size_t, size_t, int *);
44 void *testCustomNew() {
45   int x[1] = {1};
46   clang_analyzer_eval(*x == 1); // expected-warning{{TRUE}};
47 
48   void *y = new (0, x) int;
49   clang_analyzer_eval(*x == 1); // expected-warning{{UNKNOWN}};
50 
51   return y; // no-warning
52 }
53 
54 void *operator new(size_t, void *, void *);
55 void *testCustomNewMalloc() {
56   int *x = (int *)malloc(sizeof(int));
57 
58   // Should be no-warning (the custom allocator could have freed x).
59   void *y = new (0, x) int; // no-warning
60 
61   return y;
62 }
63 
64 void testScalarInitialization() {
65   int *n = new int(3);
66   clang_analyzer_eval(*n == 3); // expected-warning{{TRUE}}
67 
68   new (n) int();
69   clang_analyzer_eval(*n == 0); // expected-warning{{TRUE}}
70 
71   new (n) int{3};
72   clang_analyzer_eval(*n == 3); // expected-warning{{TRUE}}
73 
74   new (n) int{};
75   clang_analyzer_eval(*n == 0); // expected-warning{{TRUE}}
76 }
77 
78 struct PtrWrapper {
79   int *x;
80 
81   PtrWrapper(int *input) : x(input) {}
82 };
83 
84 PtrWrapper *testNewInvalidation() {
85   // Ensure that we don't consider this a leak.
86   return new PtrWrapper(static_cast<int *>(malloc(4))); // no-warning
87 }
88 
89 void testNewInvalidationPlacement(PtrWrapper *w) {
90   // Ensure that we don't consider this a leak.
91   new (w) PtrWrapper(static_cast<int *>(malloc(4))); // no-warning
92 }
93 
94 int **testNewInvalidationScalar() {
95   // Ensure that we don't consider this a leak.
96   return new (int *)(static_cast<int *>(malloc(4))); // no-warning
97 }
98 
99 void testNewInvalidationScalarPlacement(int **p) {
100   // Ensure that we don't consider this a leak.
101   new (p) (int *)(static_cast<int *>(malloc(4))); // no-warning
102 }
103 
104 void testCacheOut(PtrWrapper w) {
105   extern bool coin();
106   if (coin())
107     w.x = 0;
108   new (&w.x) (int*)(0); // we cache out here; don't crash
109 }
110 
111 void testUseAfter(int *p) {
112   SomeClass *c = new SomeClass;
113   free(p);
114   c->f(p); // expected-warning{{Use of memory after it is freed}}
115   delete c;
116 }
117 
118 //--------------------------------------------------------------------
119 // Check for intersection with other checkers from MallocChecker.cpp
120 // bounded with unix.Malloc
121 //--------------------------------------------------------------------
122 
123 // new/delete oparators are subjects of cplusplus.NewDelete.
124 void testNewDeleteNoWarn() {
125   int i;
126   delete &i; // no-warning
127 
128   int *p1 = new int;
129   delete ++p1; // no-warning
130 
131   int *p2 = new int;
132   delete p2;
133   delete p2; // no-warning
134 
135   int *p3 = new int; // no-warning
136 }
137 
138 // unix.Malloc does not know about operators new/delete.
139 void testDeleteMallocked() {
140   int *x = (int *)malloc(sizeof(int));
141   delete x; // FIXME: Should detect pointer escape and keep silent after 'delete' is modeled properly.
142 } // expected-warning{{Potential leak of memory pointed to by 'x'}}
143 
144 void testDeleteOpAfterFree() {
145   int *p = (int *)malloc(sizeof(int));
146   free(p);
147   operator delete(p); // expected-warning{{Use of memory after it is freed}}
148 }
149 
150 void testDeleteAfterFree() {
151   int *p = (int *)malloc(sizeof(int));
152   free(p);
153   delete p; // expected-warning{{Use of memory after it is freed}}
154 }
155 
156 void testStandardPlacementNewAfterFree() {
157   int *p = (int *)malloc(sizeof(int));
158   free(p);
159   p = new(p) int; // expected-warning{{Use of memory after it is freed}}
160 }
161 
162 void testCustomPlacementNewAfterFree() {
163   int *p = (int *)malloc(sizeof(int));
164   free(p);
165   p = new(0, p) int; // expected-warning{{Use of memory after it is freed}}
166 }
167 
168 void testUsingThisAfterDelete() {
169   SomeClass *c = new SomeClass;
170   delete c;
171   c->f(0); // no-warning
172 }
173 
174 void testAggregateNew() {
175   struct Point { int x, y; };
176   new Point{1, 2}; // no crash
177 
178   Point p;
179   new (&p) Point{1, 2}; // no crash
180   clang_analyzer_eval(p.x == 1); // expected-warning{{TRUE}}
181   clang_analyzer_eval(p.y == 2); // expected-warning{{TRUE}}
182 }
183 
184 //--------------------------------
185 // Incorrectly-modelled behavior
186 //--------------------------------
187 
188 int testNoInitialization() {
189   int *n = new int;
190 
191   // Should warn that *n is uninitialized.
192   if (*n) { // no-warning
193     delete n;
194     return 0;
195   }
196   delete n;
197   return 1;
198 }
199 
200 int testNoInitializationPlacement() {
201   int n;
202   new (&n) int;
203 
204   if (n) { // expected-warning{{Branch condition evaluates to a garbage value}}
205     return 0;
206   }
207   return 1;
208 }
209 
210 // Test modelling destructor call on call to delete
211 class IntPair{
212 public:
213   int x;
214   int y;
215   IntPair() {};
216   ~IntPair() {x = x/y;}; //expected-warning {{Division by zero}}
217 };
218 
219 void testCallToDestructor() {
220   IntPair *b = new IntPair();
221   b->x = 1;
222   b->y = 0;
223   delete b; // This results in divide by zero in destructor
224 }
225 
226 // Test Deleting a value that's passed as an argument.
227 class DerefClass{
228 public:
229   int *x;
230   DerefClass() {};
231   ~DerefClass() {*x = 1;}; //expected-warning {{Dereference of null pointer (loaded from field 'x')}}
232 };
233 
234 void testDestCall(DerefClass *arg) {
235   delete arg;
236 }
237 
238 void test_delete_dtor_Arg() {
239   DerefClass *pair = new DerefClass();
240   pair->x = 0;
241   testDestCall(pair);
242 }
243 
244 //Deleting the address of a local variable, null pointer
245 void abort(void) __attribute__((noreturn));
246 
247 class NoReturnDtor {
248 public:
249   NoReturnDtor() {}
250   ~NoReturnDtor() {abort();}
251 };
252 
253 void test_delete_dtor_LocalVar() {
254   NoReturnDtor test;
255   delete &test; // no warn or crash
256 }
257 
258 class DerivedNoReturn:public NoReturnDtor {
259 public:
260   DerivedNoReturn() {};
261   ~DerivedNoReturn() {};
262 };
263 
264 void testNullDtorDerived() {
265   DerivedNoReturn *p = new DerivedNoReturn();
266   delete p; // Calls the base destructor which aborts, checked below
267   clang_analyzer_eval(true); // no warn
268 }
269 
270 //Deleting a non-class pointer should not crash/warn
271 void test_var_delete() {
272   int *v = new int;
273   delete v;  // no crash/warn
274   clang_analyzer_eval(true); // expected-warning{{TRUE}}
275 }
276 
277 void test_array_delete() {
278   class C {
279   public:
280     ~C() {}
281   };
282 
283   auto c1 = new C[2][3];
284   delete[] c1; // no-crash // no-warning
285 
286   C c2[4];
287   // FIXME: Should warn.
288   delete[] &c2; // no-crash
289 
290   C c3[7][6];
291   // FIXME: Should warn.
292   delete[] &c3; // no-crash
293 }
294 
295 void testDeleteNull() {
296   NoReturnDtor *foo = 0;
297   delete foo; // should not call destructor, checked below
298   clang_analyzer_eval(true); // expected-warning{{TRUE}}
299 }
300 
301 void testNullAssigneddtor() {
302   NoReturnDtor *p = 0;
303   NoReturnDtor *s = p;
304   delete s; // should not call destructor, checked below
305   clang_analyzer_eval(true); // expected-warning{{TRUE}}
306 }
307 
308 void deleteArg(NoReturnDtor *test) {
309   delete test;
310 }
311 
312 void testNulldtorArg() {
313   NoReturnDtor *p = 0;
314   deleteArg(p);
315   clang_analyzer_eval(true); // expected-warning{{TRUE}}
316 }
317 
318 void testDeleteUnknown(NoReturnDtor *foo) {
319   delete foo; // should assume non-null and call noreturn destructor
320   clang_analyzer_eval(true); // no-warning
321 }
322 
323 void testArrayNull() {
324   NoReturnDtor *fooArray = 0;
325   delete[] fooArray; // should not call destructor, checked below
326   clang_analyzer_eval(true); // expected-warning{{TRUE}}
327 }
328 
329 void testArrayDestr() {
330   NoReturnDtor *p = new NoReturnDtor[2];
331   delete[] p; // Calls the base destructor which aborts, checked below
332    //TODO: clang_analyzer_eval should not be called
333   clang_analyzer_eval(true); // expected-warning{{TRUE}}
334 }
335 
336 // Invalidate Region even in case of default destructor
337 class InvalidateDestTest {
338 public:
339   int x;
340   int *y;
341   ~InvalidateDestTest();
342 };
343 
344 int test_member_invalidation() {
345 
346   //test invalidation of member variable
347   InvalidateDestTest *test = new InvalidateDestTest();
348   test->x = 5;
349   int *k = &(test->x);
350   clang_analyzer_eval(*k == 5); // expected-warning{{TRUE}}
351   delete test;
352   clang_analyzer_eval(*k == 5); // expected-warning{{UNKNOWN}}
353 
354   //test invalidation of member pointer
355   int localVar = 5;
356   test = new InvalidateDestTest();
357   test->y = &localVar;
358   delete test;
359   clang_analyzer_eval(localVar == 5); // expected-warning{{UNKNOWN}}
360 
361   // Test aray elements are invalidated.
362   int Var1 = 5;
363   int Var2 = 5;
364   InvalidateDestTest *a = new InvalidateDestTest[2];
365   a[0].y = &Var1;
366   a[1].y = &Var2;
367   delete[] a;
368   clang_analyzer_eval(Var1 == 5); // expected-warning{{UNKNOWN}}
369   clang_analyzer_eval(Var2 == 5); // expected-warning{{UNKNOWN}}
370   return 0;
371 }
372