[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / test / Analysis / new.cpp
blob3542b5c594b508de86aa132b6a34dc8e26a2780e
1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -std=c++11 -verify -analyzer-config eagerly-assume=false %s
2 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -std=c++11 -DTEST_INLINABLE_ALLOCATORS -verify -analyzer-config eagerly-assume=false %s
3 #include "Inputs/system-header-simulator-cxx.h"
5 void clang_analyzer_eval(bool);
6 void clang_analyzer_warnIfReached();
8 typedef __typeof__(sizeof(int)) size_t;
9 extern "C" void *malloc(size_t);
10 extern "C" void free(void *);
12 int someGlobal;
14 class SomeClass {
15 public:
16 void f(int *p);
19 void testImplicitlyDeclaredGlobalNew() {
20 if (someGlobal != 0)
21 return;
23 // This used to crash because the global operator new is being implicitly
24 // declared and it does not have a valid source location. (PR13090)
25 void *x = ::operator new(0);
26 ::operator delete(x);
28 // Check that the new/delete did not invalidate someGlobal;
29 clang_analyzer_eval(someGlobal == 0); // expected-warning{{TRUE}}
32 void *testPlacementNew() {
33 int *x = (int *)malloc(sizeof(int));
34 *x = 1;
35 clang_analyzer_eval(*x == 1); // expected-warning{{TRUE}};
37 void *y = new (x) int;
38 clang_analyzer_eval(x == y); // expected-warning{{TRUE}};
39 clang_analyzer_eval(*x == 1); // expected-warning{{TRUE}};
41 return y;
44 void *operator new(size_t, size_t, int *);
45 void *testCustomNew() {
46 int x[1] = {1};
47 clang_analyzer_eval(*x == 1); // expected-warning{{TRUE}};
49 void *y = new (0, x) int;
50 clang_analyzer_eval(*x == 1); // expected-warning{{UNKNOWN}};
52 return y; // no-warning
55 void *operator new(size_t, void *, void *);
56 void *testCustomNewMalloc() {
57 int *x = (int *)malloc(sizeof(int));
59 // Should be no-warning (the custom allocator could have freed x).
60 void *y = new (0, x) int; // no-warning
62 return y;
65 void testScalarInitialization() {
66 int *n = new int(3);
67 clang_analyzer_eval(*n == 3); // expected-warning{{TRUE}}
69 new (n) int();
70 clang_analyzer_eval(*n == 0); // expected-warning{{TRUE}}
72 new (n) int{3};
73 clang_analyzer_eval(*n == 3); // expected-warning{{TRUE}}
75 new (n) int{};
76 clang_analyzer_eval(*n == 0); // expected-warning{{TRUE}}
79 struct PtrWrapper {
80 int *x;
82 PtrWrapper(int *input) : x(input) {}
85 PtrWrapper *testNewInvalidation() {
86 // Ensure that we don't consider this a leak.
87 return new PtrWrapper(static_cast<int *>(malloc(4))); // no-warning
90 void testNewInvalidationPlacement(PtrWrapper *w) {
91 // Ensure that we don't consider this a leak.
92 new (w) PtrWrapper(static_cast<int *>(malloc(4))); // no-warning
95 int **testNewInvalidationScalar() {
96 // Ensure that we don't consider this a leak.
97 return new (int *)(static_cast<int *>(malloc(4))); // no-warning
100 void testNewInvalidationScalarPlacement(int **p) {
101 // Ensure that we don't consider this a leak.
102 new (p) (int *)(static_cast<int *>(malloc(4))); // no-warning
105 void testCacheOut(PtrWrapper w) {
106 extern bool coin();
107 if (coin())
108 w.x = 0;
109 new (&w.x) (int*)(0); // we cache out here; don't crash
112 void testUseAfter(int *p) {
113 SomeClass *c = new SomeClass;
114 free(p);
115 c->f(p); // expected-warning{{Use of memory after it is freed}}
116 delete c;
119 // new/delete oparators are subjects of cplusplus.NewDelete.
120 void testNewDeleteNoWarn() {
121 int i;
122 delete &i; // no-warning
124 int *p1 = new int;
125 delete ++p1; // no-warning
127 int *p2 = new int;
128 delete p2;
129 delete p2; // no-warning
131 int *p3 = new int; // no-warning
134 void testDeleteMallocked() {
135 int *x = (int *)malloc(sizeof(int));
136 // unix.MismatchedDeallocator would catch this, but we're not testing it here.
137 delete x;
140 void testDeleteOpAfterFree() {
141 int *p = (int *)malloc(sizeof(int));
142 free(p);
143 operator delete(p); // expected-warning{{Use of memory after it is freed}}
146 void testDeleteAfterFree() {
147 int *p = (int *)malloc(sizeof(int));
148 free(p);
149 delete p; // expected-warning{{Use of memory after it is freed}}
152 void testStandardPlacementNewAfterFree() {
153 int *p = (int *)malloc(sizeof(int));
154 free(p);
155 p = new(p) int; // expected-warning{{Use of memory after it is freed}}
158 void testCustomPlacementNewAfterFree() {
159 int *p = (int *)malloc(sizeof(int));
160 free(p);
161 p = new(0, p) int; // expected-warning{{Use of memory after it is freed}}
164 void testUsingThisAfterDelete() {
165 SomeClass *c = new SomeClass;
166 delete c;
167 c->f(0); // no-warning
170 void testAggregateNew() {
171 struct Point { int x, y; };
172 new Point{1, 2}; // no crash
174 Point p;
175 new (&p) Point{1, 2}; // no crash
176 clang_analyzer_eval(p.x == 1); // expected-warning{{TRUE}}
177 clang_analyzer_eval(p.y == 2); // expected-warning{{TRUE}}
180 int testNoInitialization() {
181 int *n = new int;
183 if (*n) { // expected-warning{{Branch condition evaluates to a garbage value [core.uninitialized.Branch]}}
184 delete n;
185 return 0;
187 delete n;
188 return 1;
191 //===----------------------------------------------------------------------===//
192 // Incorrectly-modelled behavior.
193 //===----------------------------------------------------------------------===//
195 int testNoInitializationPlacement() {
196 int n;
197 new (&n) int;
199 if (n) { // expected-warning{{Branch condition evaluates to a garbage value}}
200 return 0;
202 return 1;
205 // Test modelling destructor call on call to delete
206 class IntPair{
207 public:
208 int x;
209 int y;
210 IntPair() {};
211 ~IntPair() {x = x/y;}; //expected-warning {{Division by zero}}
214 void testCallToDestructor() {
215 IntPair *b = new IntPair();
216 b->x = 1;
217 b->y = 0;
218 delete b; // This results in divide by zero in destructor
221 // Test Deleting a value that's passed as an argument.
222 class DerefClass{
223 public:
224 int *x;
225 DerefClass() {};
226 ~DerefClass() {*x = 1;}; //expected-warning {{Dereference of null pointer (loaded from field 'x')}}
229 void testDestCall(DerefClass *arg) {
230 delete arg;
233 void test_delete_dtor_Arg() {
234 DerefClass *pair = new DerefClass();
235 pair->x = 0;
236 testDestCall(pair);
239 //Deleting the address of a local variable, null pointer
240 void abort(void) __attribute__((noreturn));
242 class NoReturnDtor {
243 public:
244 NoReturnDtor() {}
245 ~NoReturnDtor() {abort();}
248 void test_delete_dtor_LocalVar() {
249 NoReturnDtor test;
250 delete &test; // no warn or crash
253 class DerivedNoReturn:public NoReturnDtor {
254 public:
255 DerivedNoReturn() {};
256 ~DerivedNoReturn() {};
259 void testNullDtorDerived() {
260 DerivedNoReturn *p = new DerivedNoReturn();
261 delete p; // Calls the base destructor which aborts, checked below
262 clang_analyzer_eval(true); // no warn
265 //Deleting a non-class pointer should not crash/warn
266 void test_var_delete() {
267 int *v = new int;
268 delete v; // no crash/warn
269 clang_analyzer_eval(true); // expected-warning{{TRUE}}
272 void test_array_delete() {
273 class C {
274 public:
275 ~C() {}
278 auto c1 = new C[2][3];
279 delete[] c1; // no-crash // no-warning
281 C c2[4];
282 // FIXME: Should warn.
283 delete[] &c2; // no-crash
285 C c3[7][6];
286 // FIXME: Should warn.
287 delete[] &c3; // no-crash
290 void testDeleteNull() {
291 NoReturnDtor *foo = 0;
292 delete foo; // should not call destructor, checked below
293 clang_analyzer_eval(true); // expected-warning{{TRUE}}
296 void testNullAssigneddtor() {
297 NoReturnDtor *p = 0;
298 NoReturnDtor *s = p;
299 delete s; // should not call destructor, checked below
300 clang_analyzer_eval(true); // expected-warning{{TRUE}}
303 void deleteArg(NoReturnDtor *test) {
304 delete test;
307 void testNulldtorArg() {
308 NoReturnDtor *p = 0;
309 deleteArg(p);
310 clang_analyzer_eval(true); // expected-warning{{TRUE}}
313 void testDeleteUnknown(NoReturnDtor *foo) {
314 delete foo; // should assume non-null and call noreturn destructor
315 clang_analyzer_eval(true); // no-warning
318 void testArrayNull() {
319 NoReturnDtor *fooArray = 0;
320 delete[] fooArray; // should not call destructor, checked below
321 clang_analyzer_eval(true); // expected-warning{{TRUE}}
324 void testArrayDestr() {
325 NoReturnDtor *p = new NoReturnDtor[2];
326 delete[] p;
327 clang_analyzer_warnIfReached(); // no-warning
330 // Invalidate Region even in case of default destructor
331 class InvalidateDestTest {
332 public:
333 int x;
334 int *y;
335 ~InvalidateDestTest();
338 int test_member_invalidation() {
340 //test invalidation of member variable
341 InvalidateDestTest *test = new InvalidateDestTest();
342 test->x = 5;
343 int *k = &(test->x);
344 clang_analyzer_eval(*k == 5); // expected-warning{{TRUE}}
345 delete test;
346 clang_analyzer_eval(*k == 5); // expected-warning{{UNKNOWN}}
348 //test invalidation of member pointer
349 int localVar = 5;
350 test = new InvalidateDestTest();
351 test->y = &localVar;
352 delete test;
353 clang_analyzer_eval(localVar == 5); // expected-warning{{UNKNOWN}}
355 // Test aray elements are invalidated.
356 int Var1 = 5;
357 int Var2 = 5;
358 InvalidateDestTest *a = new InvalidateDestTest[2];
359 a[0].y = &Var1;
360 a[1].y = &Var2;
361 delete[] a;
362 clang_analyzer_eval(Var1 == 5); // expected-warning{{UNKNOWN}}
363 clang_analyzer_eval(Var2 == 5); // expected-warning{{UNKNOWN}}
364 return 0;