1*67e74705SXin Li // RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -fblocks -verify %s
2*67e74705SXin Li // RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -fblocks -verify %s
3*67e74705SXin Li #include "Inputs/system-header-simulator-cxx.h"
4*67e74705SXin Li
5*67e74705SXin Li typedef __typeof__(sizeof(int)) size_t;
6*67e74705SXin Li extern "C" void *malloc(size_t);
7*67e74705SXin Li extern "C" void free (void* ptr);
8*67e74705SXin Li int *global;
9*67e74705SXin Li
10*67e74705SXin Li //------------------
11*67e74705SXin Li // check for leaks
12*67e74705SXin Li //------------------
13*67e74705SXin Li
14*67e74705SXin Li //----- Standard non-placement operators
testGlobalOpNew()15*67e74705SXin Li void testGlobalOpNew() {
16*67e74705SXin Li void *p = operator new(0);
17*67e74705SXin Li }
18*67e74705SXin Li #ifdef LEAKS
19*67e74705SXin Li // expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
20*67e74705SXin Li #endif
21*67e74705SXin Li
testGlobalOpNewArray()22*67e74705SXin Li void testGlobalOpNewArray() {
23*67e74705SXin Li void *p = operator new[](0);
24*67e74705SXin Li }
25*67e74705SXin Li #ifdef LEAKS
26*67e74705SXin Li // expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
27*67e74705SXin Li #endif
28*67e74705SXin Li
testGlobalNewExpr()29*67e74705SXin Li void testGlobalNewExpr() {
30*67e74705SXin Li int *p = new int;
31*67e74705SXin Li }
32*67e74705SXin Li #ifdef LEAKS
33*67e74705SXin Li // expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
34*67e74705SXin Li #endif
35*67e74705SXin Li
testGlobalNewExprArray()36*67e74705SXin Li void testGlobalNewExprArray() {
37*67e74705SXin Li int *p = new int[0];
38*67e74705SXin Li }
39*67e74705SXin Li #ifdef LEAKS
40*67e74705SXin Li // expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
41*67e74705SXin Li #endif
42*67e74705SXin Li
43*67e74705SXin Li //----- Standard nothrow placement operators
testGlobalNoThrowPlacementOpNewBeforeOverload()44*67e74705SXin Li void testGlobalNoThrowPlacementOpNewBeforeOverload() {
45*67e74705SXin Li void *p = operator new(0, std::nothrow);
46*67e74705SXin Li }
47*67e74705SXin Li #ifdef LEAKS
48*67e74705SXin Li // expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
49*67e74705SXin Li #endif
50*67e74705SXin Li
testGlobalNoThrowPlacementExprNewBeforeOverload()51*67e74705SXin Li void testGlobalNoThrowPlacementExprNewBeforeOverload() {
52*67e74705SXin Li int *p = new(std::nothrow) int;
53*67e74705SXin Li }
54*67e74705SXin Li #ifdef LEAKS
55*67e74705SXin Li // expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
56*67e74705SXin Li #endif
57*67e74705SXin Li
58*67e74705SXin Li //----- Standard pointer placement operators
testGlobalPointerPlacementNew()59*67e74705SXin Li void testGlobalPointerPlacementNew() {
60*67e74705SXin Li int i;
61*67e74705SXin Li
62*67e74705SXin Li void *p1 = operator new(0, &i); // no warn
63*67e74705SXin Li
64*67e74705SXin Li void *p2 = operator new[](0, &i); // no warn
65*67e74705SXin Li
66*67e74705SXin Li int *p3 = new(&i) int; // no warn
67*67e74705SXin Li
68*67e74705SXin Li int *p4 = new(&i) int[0]; // no warn
69*67e74705SXin Li }
70*67e74705SXin Li
71*67e74705SXin Li //----- Other cases
testNewMemoryIsInHeap()72*67e74705SXin Li void testNewMemoryIsInHeap() {
73*67e74705SXin Li int *p = new int;
74*67e74705SXin Li if (global != p) // condition is always true as 'p' wraps a heap region that
75*67e74705SXin Li // is different from a region wrapped by 'global'
76*67e74705SXin Li global = p; // pointer escapes
77*67e74705SXin Li }
78*67e74705SXin Li
79*67e74705SXin Li struct PtrWrapper {
80*67e74705SXin Li int *x;
81*67e74705SXin Li
PtrWrapperPtrWrapper82*67e74705SXin Li PtrWrapper(int *input) : x(input) {}
83*67e74705SXin Li };
84*67e74705SXin Li
testNewInvalidationPlacement(PtrWrapper * w)85*67e74705SXin Li void testNewInvalidationPlacement(PtrWrapper *w) {
86*67e74705SXin Li // Ensure that we don't consider this a leak.
87*67e74705SXin Li new (w) PtrWrapper(new int); // no warn
88*67e74705SXin Li }
89*67e74705SXin Li
90*67e74705SXin Li //-----------------------------------------
91*67e74705SXin Li // check for usage of zero-allocated memory
92*67e74705SXin Li //-----------------------------------------
93*67e74705SXin Li
testUseZeroAlloc1()94*67e74705SXin Li void testUseZeroAlloc1() {
95*67e74705SXin Li int *p = (int *)operator new(0);
96*67e74705SXin Li *p = 1; // expected-warning {{Use of zero-allocated memory}}
97*67e74705SXin Li delete p;
98*67e74705SXin Li }
99*67e74705SXin Li
testUseZeroAlloc2()100*67e74705SXin Li int testUseZeroAlloc2() {
101*67e74705SXin Li int *p = (int *)operator new[](0);
102*67e74705SXin Li return p[0]; // expected-warning {{Use of zero-allocated memory}}
103*67e74705SXin Li delete[] p;
104*67e74705SXin Li }
105*67e74705SXin Li
106*67e74705SXin Li void f(int);
107*67e74705SXin Li
testUseZeroAlloc3()108*67e74705SXin Li void testUseZeroAlloc3() {
109*67e74705SXin Li int *p = new int[0];
110*67e74705SXin Li f(*p); // expected-warning {{Use of zero-allocated memory}}
111*67e74705SXin Li delete[] p;
112*67e74705SXin Li }
113*67e74705SXin Li
114*67e74705SXin Li //---------------
115*67e74705SXin Li // other checks
116*67e74705SXin Li //---------------
117*67e74705SXin Li
118*67e74705SXin Li class SomeClass {
119*67e74705SXin Li public:
120*67e74705SXin Li void f(int *p);
121*67e74705SXin Li };
122*67e74705SXin Li
123*67e74705SXin Li void f(int *p1, int *p2 = 0, int *p3 = 0);
124*67e74705SXin Li void g(SomeClass &c, ...);
125*67e74705SXin Li
testUseFirstArgAfterDelete()126*67e74705SXin Li void testUseFirstArgAfterDelete() {
127*67e74705SXin Li int *p = new int;
128*67e74705SXin Li delete p;
129*67e74705SXin Li f(p); // expected-warning{{Use of memory after it is freed}}
130*67e74705SXin Li }
131*67e74705SXin Li
testUseMiddleArgAfterDelete(int * p)132*67e74705SXin Li void testUseMiddleArgAfterDelete(int *p) {
133*67e74705SXin Li delete p;
134*67e74705SXin Li f(0, p); // expected-warning{{Use of memory after it is freed}}
135*67e74705SXin Li }
136*67e74705SXin Li
testUseLastArgAfterDelete(int * p)137*67e74705SXin Li void testUseLastArgAfterDelete(int *p) {
138*67e74705SXin Li delete p;
139*67e74705SXin Li f(0, 0, p); // expected-warning{{Use of memory after it is freed}}
140*67e74705SXin Li }
141*67e74705SXin Li
testUseSeveralArgsAfterDelete(int * p)142*67e74705SXin Li void testUseSeveralArgsAfterDelete(int *p) {
143*67e74705SXin Li delete p;
144*67e74705SXin Li f(p, p, p); // expected-warning{{Use of memory after it is freed}}
145*67e74705SXin Li }
146*67e74705SXin Li
testUseRefArgAfterDelete(SomeClass & c)147*67e74705SXin Li void testUseRefArgAfterDelete(SomeClass &c) {
148*67e74705SXin Li delete &c;
149*67e74705SXin Li g(c); // expected-warning{{Use of memory after it is freed}}
150*67e74705SXin Li }
151*67e74705SXin Li
testVariadicArgAfterDelete()152*67e74705SXin Li void testVariadicArgAfterDelete() {
153*67e74705SXin Li SomeClass c;
154*67e74705SXin Li int *p = new int;
155*67e74705SXin Li delete p;
156*67e74705SXin Li g(c, 0, p); // expected-warning{{Use of memory after it is freed}}
157*67e74705SXin Li }
158*67e74705SXin Li
testUseMethodArgAfterDelete(int * p)159*67e74705SXin Li void testUseMethodArgAfterDelete(int *p) {
160*67e74705SXin Li SomeClass *c = new SomeClass;
161*67e74705SXin Li delete p;
162*67e74705SXin Li c->f(p); // expected-warning{{Use of memory after it is freed}}
163*67e74705SXin Li }
164*67e74705SXin Li
testUseThisAfterDelete()165*67e74705SXin Li void testUseThisAfterDelete() {
166*67e74705SXin Li SomeClass *c = new SomeClass;
167*67e74705SXin Li delete c;
168*67e74705SXin Li c->f(0); // expected-warning{{Use of memory after it is freed}}
169*67e74705SXin Li }
170*67e74705SXin Li
testDoubleDelete()171*67e74705SXin Li void testDoubleDelete() {
172*67e74705SXin Li int *p = new int;
173*67e74705SXin Li delete p;
174*67e74705SXin Li delete p; // expected-warning{{Attempt to free released memory}}
175*67e74705SXin Li }
176*67e74705SXin Li
testExprDeleteArg()177*67e74705SXin Li void testExprDeleteArg() {
178*67e74705SXin Li int i;
179*67e74705SXin Li delete &i; // expected-warning{{Argument to 'delete' is the address of the local variable 'i', which is not memory allocated by 'new'}}
180*67e74705SXin Li }
181*67e74705SXin Li
testExprDeleteArrArg()182*67e74705SXin Li void testExprDeleteArrArg() {
183*67e74705SXin Li int i;
184*67e74705SXin Li delete[] &i; // expected-warning{{Argument to 'delete[]' is the address of the local variable 'i', which is not memory allocated by 'new[]'}}
185*67e74705SXin Li }
186*67e74705SXin Li
testAllocDeallocNames()187*67e74705SXin Li void testAllocDeallocNames() {
188*67e74705SXin Li int *p = new(std::nothrow) int[1];
189*67e74705SXin Li delete[] (++p); // expected-warning{{Argument to 'delete[]' is offset by 4 bytes from the start of memory allocated by 'new[]'}}
190*67e74705SXin Li }
191*67e74705SXin Li
192*67e74705SXin Li //--------------------------------
193*67e74705SXin Li // Test escape of newed const pointer. Note, a const pointer can be deleted.
194*67e74705SXin Li //--------------------------------
195*67e74705SXin Li struct StWithConstPtr {
196*67e74705SXin Li const int *memp;
197*67e74705SXin Li };
198*67e74705SXin Li void escape(const int &x);
199*67e74705SXin Li void escapeStruct(const StWithConstPtr &x);
200*67e74705SXin Li void escapePtr(const StWithConstPtr *x);
201*67e74705SXin Li void escapeVoidPtr(const void *x);
202*67e74705SXin Li
testConstEscape()203*67e74705SXin Li void testConstEscape() {
204*67e74705SXin Li int *p = new int(1);
205*67e74705SXin Li escape(*p);
206*67e74705SXin Li } // no-warning
207*67e74705SXin Li
testConstEscapeStruct()208*67e74705SXin Li void testConstEscapeStruct() {
209*67e74705SXin Li StWithConstPtr *St = new StWithConstPtr();
210*67e74705SXin Li escapeStruct(*St);
211*67e74705SXin Li } // no-warning
212*67e74705SXin Li
testConstEscapeStructPtr()213*67e74705SXin Li void testConstEscapeStructPtr() {
214*67e74705SXin Li StWithConstPtr *St = new StWithConstPtr();
215*67e74705SXin Li escapePtr(St);
216*67e74705SXin Li } // no-warning
217*67e74705SXin Li
testConstEscapeMember()218*67e74705SXin Li void testConstEscapeMember() {
219*67e74705SXin Li StWithConstPtr St;
220*67e74705SXin Li St.memp = new int(2);
221*67e74705SXin Li escapeVoidPtr(St.memp);
222*67e74705SXin Li } // no-warning
223*67e74705SXin Li
testConstEscapePlacementNew()224*67e74705SXin Li void testConstEscapePlacementNew() {
225*67e74705SXin Li int *x = (int *)malloc(sizeof(int));
226*67e74705SXin Li void *y = new (x) int;
227*67e74705SXin Li escapeVoidPtr(y);
228*67e74705SXin Li } // no-warning
229*67e74705SXin Li
230*67e74705SXin Li //============== Test Uninitialized delete delete[]========================
testUninitDelete()231*67e74705SXin Li void testUninitDelete() {
232*67e74705SXin Li int *x;
233*67e74705SXin Li int * y = new int;
234*67e74705SXin Li delete y;
235*67e74705SXin Li delete x; // expected-warning{{Argument to 'delete' is uninitialized}}
236*67e74705SXin Li }
237*67e74705SXin Li
testUninitDeleteArray()238*67e74705SXin Li void testUninitDeleteArray() {
239*67e74705SXin Li int *x;
240*67e74705SXin Li int * y = new int[5];
241*67e74705SXin Li delete[] y;
242*67e74705SXin Li delete[] x; // expected-warning{{Argument to 'delete[]' is uninitialized}}
243*67e74705SXin Li }
244*67e74705SXin Li
testUninitFree()245*67e74705SXin Li void testUninitFree() {
246*67e74705SXin Li int *x;
247*67e74705SXin Li free(x); // expected-warning{{Function call argument is an uninitialized value}}
248*67e74705SXin Li }
249*67e74705SXin Li
testUninitDeleteSink()250*67e74705SXin Li void testUninitDeleteSink() {
251*67e74705SXin Li int *x;
252*67e74705SXin Li delete x; // expected-warning{{Argument to 'delete' is uninitialized}}
253*67e74705SXin Li (*(volatile int *)0 = 1); // no warn
254*67e74705SXin Li }
255*67e74705SXin Li
testUninitDeleteArraySink()256*67e74705SXin Li void testUninitDeleteArraySink() {
257*67e74705SXin Li int *x;
258*67e74705SXin Li delete[] x; // expected-warning{{Argument to 'delete[]' is uninitialized}}
259*67e74705SXin Li (*(volatile int *)0 = 1); // no warn
260*67e74705SXin Li }
261*67e74705SXin Li
262*67e74705SXin Li namespace reference_count {
263*67e74705SXin Li class control_block {
264*67e74705SXin Li unsigned count;
265*67e74705SXin Li public:
control_block()266*67e74705SXin Li control_block() : count(0) {}
retain()267*67e74705SXin Li void retain() { ++count; }
release()268*67e74705SXin Li int release() { return --count; }
269*67e74705SXin Li };
270*67e74705SXin Li
271*67e74705SXin Li template <typename T>
272*67e74705SXin Li class shared_ptr {
273*67e74705SXin Li T *p;
274*67e74705SXin Li control_block *control;
275*67e74705SXin Li
276*67e74705SXin Li public:
shared_ptr()277*67e74705SXin Li shared_ptr() : p(0), control(0) {}
shared_ptr(T * p)278*67e74705SXin Li explicit shared_ptr(T *p) : p(p), control(new control_block) {
279*67e74705SXin Li control->retain();
280*67e74705SXin Li }
shared_ptr(shared_ptr & other)281*67e74705SXin Li shared_ptr(shared_ptr &other) : p(other.p), control(other.control) {
282*67e74705SXin Li if (control)
283*67e74705SXin Li control->retain();
284*67e74705SXin Li }
~shared_ptr()285*67e74705SXin Li ~shared_ptr() {
286*67e74705SXin Li if (control && control->release() == 0) {
287*67e74705SXin Li delete p;
288*67e74705SXin Li delete control;
289*67e74705SXin Li }
290*67e74705SXin Li };
291*67e74705SXin Li
operator *()292*67e74705SXin Li T &operator *() {
293*67e74705SXin Li return *p;
294*67e74705SXin Li };
295*67e74705SXin Li
swap(shared_ptr & other)296*67e74705SXin Li void swap(shared_ptr &other) {
297*67e74705SXin Li T *tmp = p;
298*67e74705SXin Li p = other.p;
299*67e74705SXin Li other.p = tmp;
300*67e74705SXin Li
301*67e74705SXin Li control_block *ctrlTmp = control;
302*67e74705SXin Li control = other.control;
303*67e74705SXin Li other.control = ctrlTmp;
304*67e74705SXin Li }
305*67e74705SXin Li };
306*67e74705SXin Li
testSingle()307*67e74705SXin Li void testSingle() {
308*67e74705SXin Li shared_ptr<int> a(new int);
309*67e74705SXin Li *a = 1;
310*67e74705SXin Li }
311*67e74705SXin Li
testDouble()312*67e74705SXin Li void testDouble() {
313*67e74705SXin Li shared_ptr<int> a(new int);
314*67e74705SXin Li shared_ptr<int> b = a;
315*67e74705SXin Li *a = 1;
316*67e74705SXin Li }
317*67e74705SXin Li
testInvalidated()318*67e74705SXin Li void testInvalidated() {
319*67e74705SXin Li shared_ptr<int> a(new int);
320*67e74705SXin Li shared_ptr<int> b = a;
321*67e74705SXin Li *a = 1;
322*67e74705SXin Li
323*67e74705SXin Li extern void use(shared_ptr<int> &);
324*67e74705SXin Li use(b);
325*67e74705SXin Li }
326*67e74705SXin Li
testNestedScope()327*67e74705SXin Li void testNestedScope() {
328*67e74705SXin Li shared_ptr<int> a(new int);
329*67e74705SXin Li {
330*67e74705SXin Li shared_ptr<int> b = a;
331*67e74705SXin Li }
332*67e74705SXin Li *a = 1;
333*67e74705SXin Li }
334*67e74705SXin Li
testSwap()335*67e74705SXin Li void testSwap() {
336*67e74705SXin Li shared_ptr<int> a(new int);
337*67e74705SXin Li shared_ptr<int> b;
338*67e74705SXin Li shared_ptr<int> c = a;
339*67e74705SXin Li shared_ptr<int>(c).swap(b);
340*67e74705SXin Li }
341*67e74705SXin Li
testUseAfterFree()342*67e74705SXin Li void testUseAfterFree() {
343*67e74705SXin Li int *p = new int;
344*67e74705SXin Li {
345*67e74705SXin Li shared_ptr<int> a(p);
346*67e74705SXin Li shared_ptr<int> b = a;
347*67e74705SXin Li }
348*67e74705SXin Li
349*67e74705SXin Li // FIXME: We should get a warning here, but we don't because we've
350*67e74705SXin Li // conservatively modeled ~shared_ptr.
351*67e74705SXin Li *p = 1;
352*67e74705SXin Li }
353*67e74705SXin Li }
354*67e74705SXin Li
355*67e74705SXin Li // Test double delete
356*67e74705SXin Li class DerefClass{
357*67e74705SXin Li public:
358*67e74705SXin Li int *x;
DerefClass()359*67e74705SXin Li DerefClass() {}
~DerefClass()360*67e74705SXin Li ~DerefClass() {*x = 1;}
361*67e74705SXin Li };
362*67e74705SXin Li
testDoubleDeleteClassInstance()363*67e74705SXin Li void testDoubleDeleteClassInstance() {
364*67e74705SXin Li DerefClass *foo = new DerefClass();
365*67e74705SXin Li delete foo;
366*67e74705SXin Li delete foo; // expected-warning {{Attempt to delete released memory}}
367*67e74705SXin Li }
368*67e74705SXin Li
369*67e74705SXin Li class EmptyClass{
370*67e74705SXin Li public:
EmptyClass()371*67e74705SXin Li EmptyClass() {}
~EmptyClass()372*67e74705SXin Li ~EmptyClass() {}
373*67e74705SXin Li };
374*67e74705SXin Li
testDoubleDeleteEmptyClass()375*67e74705SXin Li void testDoubleDeleteEmptyClass() {
376*67e74705SXin Li EmptyClass *foo = new EmptyClass();
377*67e74705SXin Li delete foo;
378*67e74705SXin Li delete foo; // expected-warning {{Attempt to delete released memory}}
379*67e74705SXin Li }
380