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 *);
19 void testImplicitlyDeclaredGlobalNew() {
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);
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));
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}};
44 void *operator new(size_t, size_t, int *);
45 void *testCustomNew() {
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
65 void testScalarInitialization() {
67 clang_analyzer_eval(*n
== 3); // expected-warning{{TRUE}}
70 clang_analyzer_eval(*n
== 0); // expected-warning{{TRUE}}
73 clang_analyzer_eval(*n
== 3); // expected-warning{{TRUE}}
76 clang_analyzer_eval(*n
== 0); // expected-warning{{TRUE}}
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
) {
109 new (&w
.x
) (int*)(0); // we cache out here; don't crash
112 void testUseAfter(int *p
) {
113 SomeClass
*c
= new SomeClass
;
115 c
->f(p
); // expected-warning{{Use of memory after it is freed}}
119 // new/delete oparators are subjects of cplusplus.NewDelete.
120 void testNewDeleteNoWarn() {
122 delete &i
; // no-warning
125 delete ++p1
; // no-warning
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.
140 void testDeleteOpAfterFree() {
141 int *p
= (int *)malloc(sizeof(int));
143 operator delete(p
); // expected-warning{{Use of memory after it is freed}}
146 void testDeleteAfterFree() {
147 int *p
= (int *)malloc(sizeof(int));
149 delete p
; // expected-warning{{Use of memory after it is freed}}
152 void testStandardPlacementNewAfterFree() {
153 int *p
= (int *)malloc(sizeof(int));
155 p
= new(p
) int; // expected-warning{{Use of memory after it is freed}}
158 void testCustomPlacementNewAfterFree() {
159 int *p
= (int *)malloc(sizeof(int));
161 p
= new(0, p
) int; // expected-warning{{Use of memory after it is freed}}
164 void testUsingThisAfterDelete() {
165 SomeClass
*c
= new SomeClass
;
167 c
->f(0); // no-warning
170 void testAggregateNew() {
171 struct Point
{ int x
, y
; };
172 new Point
{1, 2}; // no crash
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() {
183 if (*n
) { // expected-warning{{Branch condition evaluates to a garbage value [core.uninitialized.Branch]}}
191 //===----------------------------------------------------------------------===//
192 // Incorrectly-modelled behavior.
193 //===----------------------------------------------------------------------===//
195 int testNoInitializationPlacement() {
199 if (n
) { // expected-warning{{Branch condition evaluates to a garbage value}}
205 // Test modelling destructor call on call to delete
211 ~IntPair() {x
= x
/y
;}; //expected-warning {{Division by zero}}
214 void testCallToDestructor() {
215 IntPair
*b
= new IntPair();
218 delete b
; // This results in divide by zero in destructor
221 // Test Deleting a value that's passed as an argument.
226 ~DerefClass() {*x
= 1;}; //expected-warning {{Dereference of null pointer (loaded from field 'x')}}
229 void testDestCall(DerefClass
*arg
) {
233 void test_delete_dtor_Arg() {
234 DerefClass
*pair
= new DerefClass();
239 //Deleting the address of a local variable, null pointer
240 void abort(void) __attribute__((noreturn
));
245 ~NoReturnDtor() {abort();}
248 void test_delete_dtor_LocalVar() {
250 delete &test
; // no warn or crash
253 class DerivedNoReturn
:public NoReturnDtor
{
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() {
268 delete v
; // no crash/warn
269 clang_analyzer_eval(true); // expected-warning{{TRUE}}
272 void test_array_delete() {
278 auto c1
= new C
[2][3];
279 delete[] c1
; // no-crash // no-warning
282 // FIXME: Should warn.
283 delete[] &c2
; // no-crash
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() {
299 delete s
; // should not call destructor, checked below
300 clang_analyzer_eval(true); // expected-warning{{TRUE}}
303 void deleteArg(NoReturnDtor
*test
) {
307 void testNulldtorArg() {
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];
327 clang_analyzer_warnIfReached(); // no-warning
330 // Invalidate Region even in case of default destructor
331 class InvalidateDestTest
{
335 ~InvalidateDestTest();
338 int test_member_invalidation() {
340 //test invalidation of member variable
341 InvalidateDestTest
*test
= new InvalidateDestTest();
344 clang_analyzer_eval(*k
== 5); // expected-warning{{TRUE}}
346 clang_analyzer_eval(*k
== 5); // expected-warning{{UNKNOWN}}
348 //test invalidation of member pointer
350 test
= new InvalidateDestTest();
353 clang_analyzer_eval(localVar
== 5); // expected-warning{{UNKNOWN}}
355 // Test aray elements are invalidated.
358 InvalidateDestTest
*a
= new InvalidateDestTest
[2];
362 clang_analyzer_eval(Var1
== 5); // expected-warning{{UNKNOWN}}
363 clang_analyzer_eval(Var2
== 5); // expected-warning{{UNKNOWN}}