blob: 5311ff6fe76f68fb74e88351629154282223450d [file] [log] [blame]
Anton Yartsev2de19ed2013-03-25 01:35:45 +00001// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete -analyzer-store region -std=c++11 -fblocks -verify %s
2#include "Inputs/system-header-simulator-cxx.h"
3#include "Inputs/system-header-simulator-objc.h"
4
5typedef __typeof__(sizeof(int)) size_t;
6extern "C" void *malloc(size_t);
7extern "C" void free(void *);
8int *global;
9
10//------------------
11// check for leaks
12//------------------
13
Anton Yartsev69746282013-03-28 16:10:38 +000014//----- Standard non-placement operators
15void testGlobalOpNew() {
Anton Yartsev2de19ed2013-03-25 01:35:45 +000016 void *p = operator new(0);
17} // expected-warning{{Memory is never released; potential leak}}
18
Anton Yartsev69746282013-03-28 16:10:38 +000019void testGlobalOpNewArray() {
20 void *p = operator new[](0);
21} // expected-warning{{Memory is never released; potential leak}}
22
23void testGlobalNewExpr() {
Anton Yartsev2de19ed2013-03-25 01:35:45 +000024 int *p = new int;
Anton Yartsev2de19ed2013-03-25 01:35:45 +000025} // expected-warning{{Memory is never released; potential leak}}
Anton Yartsev2de19ed2013-03-25 01:35:45 +000026
Anton Yartsev69746282013-03-28 16:10:38 +000027void testGlobalNewExprArray() {
28 int *p = new int[0];
29} // expected-warning{{Memory is never released; potential leak}}
Anton Yartsev2de19ed2013-03-25 01:35:45 +000030
Anton Yartsev69746282013-03-28 16:10:38 +000031//----- Standard nothrow placement operators
32void testGlobalNoThrowPlacementOpNewBeforeOverload() {
33 void *p = operator new(0, std::nothrow);
34} // expected-warning{{Memory is never released; potential leak}}
35
36void testGlobalNoThrowPlacementExprNewBeforeOverload() {
37 int *p = new(std::nothrow) int;
38} // expected-warning{{Memory is never released; potential leak}}
39
40
41//----- Standard pointer placement operators
42void testGlobalPointerPlacementNew() {
Anton Yartsev2de19ed2013-03-25 01:35:45 +000043 int i;
Anton Yartsev2de19ed2013-03-25 01:35:45 +000044
Anton Yartsev69746282013-03-28 16:10:38 +000045 void *p1 = operator new(0, &i); // no warn
Anton Yartsev2de19ed2013-03-25 01:35:45 +000046
Anton Yartsev69746282013-03-28 16:10:38 +000047 void *p2 = operator new[](0, &i); // no warn
Anton Yartsev2de19ed2013-03-25 01:35:45 +000048
Anton Yartsev69746282013-03-28 16:10:38 +000049 int *p3 = new(&i) int; // no warn
Anton Yartsev2de19ed2013-03-25 01:35:45 +000050
Anton Yartsev69746282013-03-28 16:10:38 +000051 int *p4 = new(&i) int[0]; // no warn
Anton Yartsev2de19ed2013-03-25 01:35:45 +000052}
53
Anton Yartsev69746282013-03-28 16:10:38 +000054//----- Other cases
55void testNewMemoryIsInHeap() {
56 int *p = new int;
57 if (global != p) // condition is always true as 'p' wraps a heap region that
58 // is different from a region wrapped by 'global'
59 global = p; // pointer escapes
Anton Yartsev2de19ed2013-03-25 01:35:45 +000060}
61
Anton Yartsev69746282013-03-28 16:10:38 +000062struct PtrWrapper {
63 int *x;
Anton Yartsev2de19ed2013-03-25 01:35:45 +000064
Anton Yartsev69746282013-03-28 16:10:38 +000065 PtrWrapper(int *input) : x(input) {}
66};
Anton Yartsev2de19ed2013-03-25 01:35:45 +000067
Anton Yartsev69746282013-03-28 16:10:38 +000068void testNewInvalidationPlacement(PtrWrapper *w) {
69 // Ensure that we don't consider this a leak.
70 new (w) PtrWrapper(new int); // no warn
Anton Yartsev2de19ed2013-03-25 01:35:45 +000071}
72
73//---------------
74// other checks
75//---------------
76
77void f(int *);
78
79void testUseAfterDelete() {
80 int *p = new int;
81 delete p;
82 f(p); // expected-warning{{Use of memory after it is freed}}
83}
84
85void testDeleteAlloca() {
86 int *p = (int *)__builtin_alloca(sizeof(int));
Anton Yartsev849c7bf2013-03-28 17:05:19 +000087 delete p; // expected-warning{{Memory allocated by alloca() should not be deallocated}}
Anton Yartsev2de19ed2013-03-25 01:35:45 +000088}
89
90void testDoubleDelete() {
91 int *p = new int;
92 delete p;
93 delete p; // expected-warning{{Attempt to free released memory}}
94}
95
96void testExprDeleteArg() {
97 int i;
Anton Yartsev849c7bf2013-03-28 17:05:19 +000098 delete &i; // expected-warning{{Argument to 'delete' is the address of the local variable 'i', which is not memory allocated by 'new'}}
99}
Anton Yartsev2de19ed2013-03-25 01:35:45 +0000100
101void testExprDeleteArrArg() {
102 int i;
Anton Yartsev849c7bf2013-03-28 17:05:19 +0000103 delete[] &i; // expected-warning{{Argument to 'delete[]' is the address of the local variable 'i', which is not memory allocated by 'new[]'}}
104}
Anton Yartsev2de19ed2013-03-25 01:35:45 +0000105
106void testAllocDeallocNames() {
107 int *p = new(std::nothrow) int[1];
Anton Yartsev849c7bf2013-03-28 17:05:19 +0000108 delete[] (++p); // expected-warning{{Argument to 'delete[]' is offset by 4 bytes from the start of memory allocated by 'new[]'}}
109}
Anton Yartsev2de19ed2013-03-25 01:35:45 +0000110
111//----------------------------------------------------------------------------
112// Check for intersections with unix.Malloc and unix.MallocWithAnnotations
113// checkers bounded with cplusplus.NewDelete.
114//----------------------------------------------------------------------------
115
116// malloc()/free() are subjects of unix.Malloc and unix.MallocWithAnnotations
117void testMallocFreeNoWarn() {
118 int i;
Anton Yartsev69746282013-03-28 16:10:38 +0000119 free(&i); // no warn
Anton Yartsev2de19ed2013-03-25 01:35:45 +0000120
121 int *p1 = (int *)malloc(sizeof(int));
Anton Yartsev69746282013-03-28 16:10:38 +0000122 free(++p1); // no warn
Anton Yartsev2de19ed2013-03-25 01:35:45 +0000123
124 int *p2 = (int *)malloc(sizeof(int));
125 free(p2);
Anton Yartsev69746282013-03-28 16:10:38 +0000126 free(p2); // no warn
Anton Yartsev2de19ed2013-03-25 01:35:45 +0000127
Anton Yartsev69746282013-03-28 16:10:38 +0000128 int *p3 = (int *)malloc(sizeof(int)); // no warn
Anton Yartsev2de19ed2013-03-25 01:35:45 +0000129}
130
Anton Yartsev69746282013-03-28 16:10:38 +0000131//----- Test free standard new
132void testFreeOpNew() {
133 void *p = operator new(0);
134 free(p);
135} // expected-warning{{Memory is never released; potential leak}}
136// FIXME: Pointer should escape
137
138void testFreeNewExpr() {
Anton Yartsev2de19ed2013-03-25 01:35:45 +0000139 int *p = new int;
Anton Yartsev69746282013-03-28 16:10:38 +0000140 free(p);
141} // expected-warning{{Memory is never released; potential leak}}
142// FIXME: Pointer should escape
Anton Yartsev2de19ed2013-03-25 01:35:45 +0000143
144void testObjcFreeNewed() {
145 int *p = new int;
Anton Yartsev849c7bf2013-03-28 17:05:19 +0000146 NSData *nsdata = [NSData dataWithBytesNoCopy:p length:sizeof(int) freeWhenDone:1]; // expected-warning{{Memory is never released; potential leak}}
Anton Yartsev2de19ed2013-03-25 01:35:45 +0000147}
Anton Yartsev849c7bf2013-03-28 17:05:19 +0000148// FIXME: Pointer should escape
Anton Yartsev2de19ed2013-03-25 01:35:45 +0000149
150void testFreeAfterDelete() {
151 int *p = new int;
152 delete p;
153 free(p); // expected-warning{{Use of memory after it is freed}}
154}
155
156void testStandardPlacementNewAfterDelete() {
157 int *p = new int;
158 delete p;
159 p = new(p) int; // expected-warning{{Use of memory after it is freed}}
160}
Anna Zaks41988f32013-03-28 23:15:29 +0000161
162//--------------------------------
163// Test escape of newed const pointer. Note, a const pointer can be deleted.
164//--------------------------------
165struct StWithConstPtr {
166 const int *memp;
167};
168void escape(const int &x);
169void escapeStruct(const StWithConstPtr &x);
170void escapePtr(const StWithConstPtr *x);
171void escapeVoidPtr(const void *x);
172
173void testConstEscape() {
174 int *p = new int(1);
175 escape(*p);
176} // no-warning
177
178void testConstEscapeStruct() {
179 StWithConstPtr *St = new StWithConstPtr();
180 escapeStruct(*St);
181} // no-warning
182
183void testConstEscapeStructPtr() {
184 StWithConstPtr *St = new StWithConstPtr();
185 escapePtr(St);
186} // no-warning
187
188void testConstEscapeMember() {
189 StWithConstPtr St;
190 St.memp = new int(2);
191 escapeVoidPtr(St.memp);
192} // no-warning
193
194void testConstEscapePlacementNew() {
195 int *x = (int *)malloc(sizeof(int));
196 void *y = new (x) int;
197 escapeVoidPtr(y);
198} // no-warning
199
200