1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -fblocks -verify %s
2 // RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -fblocks -verify %s
3 // RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -fblocks -analyzer-config c++-allocator-inlining=true -verify %s
4 // RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -fblocks -analyzer-config c++-allocator-inlining=true -verify %s
5 // RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -fblocks -DTEST_INLINABLE_ALLOCATORS -verify %s
6 // RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -fblocks -DTEST_INLINABLE_ALLOCATORS -verify %s
7 // RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -fblocks -analyzer-config c++-allocator-inlining=true -DTEST_INLINABLE_ALLOCATORS -verify %s
8 // RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -fblocks -analyzer-config c++-allocator-inlining=true -DTEST_INLINABLE_ALLOCATORS -verify %s
10 #include "Inputs/system-header-simulator-cxx.h"
12 typedef __typeof__(sizeof(int)) size_t;
13 extern "C" void *malloc(size_t);
14 extern "C" void free (void* ptr);
21 //----- Standard non-placement operators
22 void testGlobalOpNew() {
23 void *p = operator new(0);
26 // expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
29 void testGlobalOpNewArray() {
30 void *p = operator new[](0);
33 // expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
36 void testGlobalNewExpr() {
40 // expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
43 void testGlobalNewExprArray() {
47 // expected-warning@-2{{Potential leak of memory pointed to by 'p'}}
50 //----- Standard nothrow placement operators
51 void testGlobalNoThrowPlacementOpNewBeforeOverload() {
52 void *p = operator new(0, std::nothrow);
55 #ifndef TEST_INLINABLE_ALLOCATORS
56 // expected-warning@-3{{Potential leak of memory pointed to by 'p'}}
60 void testGlobalNoThrowPlacementExprNewBeforeOverload() {
61 int *p = new(std::nothrow) int;
64 #ifndef TEST_INLINABLE_ALLOCATORS
65 // expected-warning@-3{{Potential leak of memory pointed to by 'p'}}
69 //----- Standard pointer placement operators
70 void testGlobalPointerPlacementNew() {
73 void *p1 = operator new(0, &i); // no warn
75 void *p2 = operator new[](0, &i); // no warn
77 int *p3 = new(&i) int; // no warn
79 int *p4 = new(&i) int[0]; // no warn
83 void testNewMemoryIsInHeap() {
85 if (global != p) // condition is always true as 'p' wraps a heap region that
86 // is different from a region wrapped by 'global'
87 global = p; // pointer escapes
93 PtrWrapper(int *input) : x(input) {}
96 void testNewInvalidationPlacement(PtrWrapper *w) {
97 // Ensure that we don't consider this a leak.
98 new (w) PtrWrapper(new int); // no warn
101 //-----------------------------------------
102 // check for usage of zero-allocated memory
103 //-----------------------------------------
105 void testUseZeroAlloc1() {
106 int *p = (int *)operator new(0);
107 *p = 1; // expected-warning {{Use of zero-allocated memory}}
111 int testUseZeroAlloc2() {
112 int *p = (int *)operator new[](0);
113 return p[0]; // expected-warning {{Use of zero-allocated memory}}
119 void testUseZeroAlloc3() {
121 f(*p); // expected-warning {{Use of zero-allocated memory}}
134 void f(int *p1, int *p2 = 0, int *p3 = 0);
135 void g(SomeClass &c, ...);
137 void testUseFirstArgAfterDelete() {
140 f(p); // expected-warning{{Use of memory after it is freed}}
143 void testUseMiddleArgAfterDelete(int *p) {
145 f(0, p); // expected-warning{{Use of memory after it is freed}}
148 void testUseLastArgAfterDelete(int *p) {
150 f(0, 0, p); // expected-warning{{Use of memory after it is freed}}
153 void testUseSeveralArgsAfterDelete(int *p) {
155 f(p, p, p); // expected-warning{{Use of memory after it is freed}}
158 void testUseRefArgAfterDelete(SomeClass &c) {
160 g(c); // expected-warning{{Use of memory after it is freed}}
163 void testVariadicArgAfterDelete() {
167 g(c, 0, p); // expected-warning{{Use of memory after it is freed}}
170 void testUseMethodArgAfterDelete(int *p) {
171 SomeClass *c = new SomeClass;
173 c->f(p); // expected-warning{{Use of memory after it is freed}}
176 void testUseThisAfterDelete() {
177 SomeClass *c = new SomeClass;
179 c->f(0); // expected-warning{{Use of memory after it is freed}}
182 void testDoubleDelete() {
185 delete p; // expected-warning{{Attempt to free released memory}}
188 void testExprDeleteArg() {
190 delete &i; // expected-warning{{Argument to 'delete' is the address of the local variable 'i', which is not memory allocated by 'new'}}
193 void testExprDeleteArrArg() {
195 delete[] &i; // expected-warning{{Argument to 'delete[]' is the address of the local variable 'i', which is not memory allocated by 'new[]'}}
198 void testAllocDeallocNames() {
199 int *p = new(std::nothrow) int[1];
201 #ifndef TEST_INLINABLE_ALLOCATORS
202 // expected-warning@-2{{Argument to 'delete[]' is offset by 4 bytes from the start of memory allocated by 'new[]'}}
206 //--------------------------------
207 // Test escape of newed const pointer. Note, a const pointer can be deleted.
208 //--------------------------------
209 struct StWithConstPtr {
212 void escape(const int &x);
213 void escapeStruct(const StWithConstPtr &x);
214 void escapePtr(const StWithConstPtr *x);
215 void escapeVoidPtr(const void *x);
217 void testConstEscape() {
222 void testConstEscapeStruct() {
223 StWithConstPtr *St = new StWithConstPtr();
227 void testConstEscapeStructPtr() {
228 StWithConstPtr *St = new StWithConstPtr();
232 void testConstEscapeMember() {
234 St.memp = new int(2);
235 escapeVoidPtr(St.memp);
238 void testConstEscapePlacementNew() {
239 int *x = (int *)malloc(sizeof(int));
240 void *y = new (x) int;
244 //============== Test Uninitialized delete delete[]========================
245 void testUninitDelete() {
249 delete x; // expected-warning{{Argument to 'delete' is uninitialized}}
252 void testUninitDeleteArray() {
254 int * y = new int[5];
256 delete[] x; // expected-warning{{Argument to 'delete[]' is uninitialized}}
259 void testUninitFree() {
261 free(x); // expected-warning{{1st function call argument is an uninitialized value}}
264 void testUninitDeleteSink() {
266 delete x; // expected-warning{{Argument to 'delete' is uninitialized}}
267 (*(volatile int *)0 = 1); // no warn
270 void testUninitDeleteArraySink() {
272 delete[] x; // expected-warning{{Argument to 'delete[]' is uninitialized}}
273 (*(volatile int *)0 = 1); // no warn
276 namespace reference_count {
277 class control_block {
280 control_block() : count(0) {}
281 void retain() { ++count; }
282 int release() { return --count; }
285 template <typename T>
288 control_block *control;
291 shared_ptr() : p(0), control(0) {}
292 explicit shared_ptr(T *p) : p(p), control(new control_block) {
295 shared_ptr(shared_ptr &other) : p(other.p), control(other.control) {
300 if (control && control->release() == 0) {
310 void swap(shared_ptr &other) {
315 control_block *ctrlTmp = control;
316 control = other.control;
317 other.control = ctrlTmp;
322 shared_ptr<int> a(new int);
327 shared_ptr<int> a(new int);
328 shared_ptr<int> b = a;
332 void testInvalidated() {
333 shared_ptr<int> a(new int);
334 shared_ptr<int> b = a;
337 extern void use(shared_ptr<int> &);
341 void testNestedScope() {
342 shared_ptr<int> a(new int);
344 shared_ptr<int> b = a;
350 shared_ptr<int> a(new int);
352 shared_ptr<int> c = a;
353 shared_ptr<int>(c).swap(b);
356 void testUseAfterFree() {
359 shared_ptr<int> a(p);
360 shared_ptr<int> b = a;
363 // FIXME: We should get a warning here, but we don't because we've
364 // conservatively modeled ~shared_ptr.
369 // Test double delete
374 ~DerefClass() {*x = 1;}
377 void testDoubleDeleteClassInstance() {
378 DerefClass *foo = new DerefClass();
380 delete foo; // expected-warning {{Attempt to delete released memory}}
389 void testDoubleDeleteEmptyClass() {
390 EmptyClass *foo = new EmptyClass();
392 delete foo; // expected-warning {{Attempt to delete released memory}}
399 struct Derived : Base {
406 void shouldNotReportLeak() {
407 Derived *p = (Derived *)allocate();