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