xref: /minix3/external/bsd/llvm/dist/clang/test/Analysis/new.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc // RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-store region -std=c++11 -verify %s
2f4a2713aSLionel Sambuc #include "Inputs/system-header-simulator-cxx.h"
3f4a2713aSLionel Sambuc 
4f4a2713aSLionel Sambuc void clang_analyzer_eval(bool);
5f4a2713aSLionel Sambuc 
6f4a2713aSLionel Sambuc typedef __typeof__(sizeof(int)) size_t;
7f4a2713aSLionel Sambuc extern "C" void *malloc(size_t);
8f4a2713aSLionel Sambuc extern "C" void free(void *);
9f4a2713aSLionel Sambuc 
10f4a2713aSLionel Sambuc int someGlobal;
11f4a2713aSLionel Sambuc 
12f4a2713aSLionel Sambuc class SomeClass {
13f4a2713aSLionel Sambuc public:
14f4a2713aSLionel Sambuc   void f(int *p);
15f4a2713aSLionel Sambuc };
16f4a2713aSLionel Sambuc 
testImplicitlyDeclaredGlobalNew()17f4a2713aSLionel Sambuc void testImplicitlyDeclaredGlobalNew() {
18f4a2713aSLionel Sambuc   if (someGlobal != 0)
19f4a2713aSLionel Sambuc     return;
20f4a2713aSLionel Sambuc 
21f4a2713aSLionel Sambuc   // This used to crash because the global operator new is being implicitly
22f4a2713aSLionel Sambuc   // declared and it does not have a valid source location. (PR13090)
23f4a2713aSLionel Sambuc   void *x = ::operator new(0);
24f4a2713aSLionel Sambuc   ::operator delete(x);
25f4a2713aSLionel Sambuc 
26f4a2713aSLionel Sambuc   // Check that the new/delete did not invalidate someGlobal;
27f4a2713aSLionel Sambuc   clang_analyzer_eval(someGlobal == 0); // expected-warning{{TRUE}}
28f4a2713aSLionel Sambuc }
29f4a2713aSLionel Sambuc 
testPlacementNew()30f4a2713aSLionel Sambuc void *testPlacementNew() {
31f4a2713aSLionel Sambuc   int *x = (int *)malloc(sizeof(int));
32f4a2713aSLionel Sambuc   *x = 1;
33f4a2713aSLionel Sambuc   clang_analyzer_eval(*x == 1); // expected-warning{{TRUE}};
34f4a2713aSLionel Sambuc 
35f4a2713aSLionel Sambuc   void *y = new (x) int;
36f4a2713aSLionel Sambuc   clang_analyzer_eval(x == y); // expected-warning{{TRUE}};
37f4a2713aSLionel Sambuc   clang_analyzer_eval(*x == 1); // expected-warning{{UNKNOWN}};
38f4a2713aSLionel Sambuc 
39f4a2713aSLionel Sambuc   return y;
40f4a2713aSLionel Sambuc }
41f4a2713aSLionel Sambuc 
42f4a2713aSLionel Sambuc void *operator new(size_t, size_t, int *);
testCustomNew()43f4a2713aSLionel Sambuc void *testCustomNew() {
44f4a2713aSLionel Sambuc   int x[1] = {1};
45f4a2713aSLionel Sambuc   clang_analyzer_eval(*x == 1); // expected-warning{{TRUE}};
46f4a2713aSLionel Sambuc 
47f4a2713aSLionel Sambuc   void *y = new (0, x) int;
48f4a2713aSLionel Sambuc   clang_analyzer_eval(*x == 1); // expected-warning{{UNKNOWN}};
49f4a2713aSLionel Sambuc 
50f4a2713aSLionel Sambuc   return y; // no-warning
51f4a2713aSLionel Sambuc }
52f4a2713aSLionel Sambuc 
53f4a2713aSLionel Sambuc void *operator new(size_t, void *, void *);
testCustomNewMalloc()54f4a2713aSLionel Sambuc void *testCustomNewMalloc() {
55f4a2713aSLionel Sambuc   int *x = (int *)malloc(sizeof(int));
56f4a2713aSLionel Sambuc 
57f4a2713aSLionel Sambuc   // Should be no-warning (the custom allocator could have freed x).
58f4a2713aSLionel Sambuc   void *y = new (0, x) int; // no-warning
59f4a2713aSLionel Sambuc 
60f4a2713aSLionel Sambuc   return y;
61f4a2713aSLionel Sambuc }
62f4a2713aSLionel Sambuc 
testScalarInitialization()63f4a2713aSLionel Sambuc void testScalarInitialization() {
64f4a2713aSLionel Sambuc   int *n = new int(3);
65f4a2713aSLionel Sambuc   clang_analyzer_eval(*n == 3); // expected-warning{{TRUE}}
66f4a2713aSLionel Sambuc 
67f4a2713aSLionel Sambuc   new (n) int();
68f4a2713aSLionel Sambuc   clang_analyzer_eval(*n == 0); // expected-warning{{TRUE}}
69f4a2713aSLionel Sambuc 
70f4a2713aSLionel Sambuc   new (n) int{3};
71f4a2713aSLionel Sambuc   clang_analyzer_eval(*n == 3); // expected-warning{{TRUE}}
72f4a2713aSLionel Sambuc 
73f4a2713aSLionel Sambuc   new (n) int{};
74f4a2713aSLionel Sambuc   clang_analyzer_eval(*n == 0); // expected-warning{{TRUE}}
75f4a2713aSLionel Sambuc }
76f4a2713aSLionel Sambuc 
77f4a2713aSLionel Sambuc struct PtrWrapper {
78f4a2713aSLionel Sambuc   int *x;
79f4a2713aSLionel Sambuc 
PtrWrapperPtrWrapper80f4a2713aSLionel Sambuc   PtrWrapper(int *input) : x(input) {}
81f4a2713aSLionel Sambuc };
82f4a2713aSLionel Sambuc 
testNewInvalidation()83f4a2713aSLionel Sambuc PtrWrapper *testNewInvalidation() {
84f4a2713aSLionel Sambuc   // Ensure that we don't consider this a leak.
85f4a2713aSLionel Sambuc   return new PtrWrapper(static_cast<int *>(malloc(4))); // no-warning
86f4a2713aSLionel Sambuc }
87f4a2713aSLionel Sambuc 
testNewInvalidationPlacement(PtrWrapper * w)88f4a2713aSLionel Sambuc void testNewInvalidationPlacement(PtrWrapper *w) {
89f4a2713aSLionel Sambuc   // Ensure that we don't consider this a leak.
90f4a2713aSLionel Sambuc   new (w) PtrWrapper(static_cast<int *>(malloc(4))); // no-warning
91f4a2713aSLionel Sambuc }
92f4a2713aSLionel Sambuc 
testNewInvalidationScalar()93f4a2713aSLionel Sambuc int **testNewInvalidationScalar() {
94f4a2713aSLionel Sambuc   // Ensure that we don't consider this a leak.
95f4a2713aSLionel Sambuc   return new (int *)(static_cast<int *>(malloc(4))); // no-warning
96f4a2713aSLionel Sambuc }
97f4a2713aSLionel Sambuc 
testNewInvalidationScalarPlacement(int ** p)98f4a2713aSLionel Sambuc void testNewInvalidationScalarPlacement(int **p) {
99f4a2713aSLionel Sambuc   // Ensure that we don't consider this a leak.
100f4a2713aSLionel Sambuc   new (p) (int *)(static_cast<int *>(malloc(4))); // no-warning
101f4a2713aSLionel Sambuc }
102f4a2713aSLionel Sambuc 
testCacheOut(PtrWrapper w)103f4a2713aSLionel Sambuc void testCacheOut(PtrWrapper w) {
104f4a2713aSLionel Sambuc   extern bool coin();
105f4a2713aSLionel Sambuc   if (coin())
106f4a2713aSLionel Sambuc     w.x = 0;
107f4a2713aSLionel Sambuc   new (&w.x) (int*)(0); // we cache out here; don't crash
108f4a2713aSLionel Sambuc }
109f4a2713aSLionel Sambuc 
testUseAfter(int * p)110f4a2713aSLionel Sambuc void testUseAfter(int *p) {
111f4a2713aSLionel Sambuc   SomeClass *c = new SomeClass;
112f4a2713aSLionel Sambuc   free(p);
113f4a2713aSLionel Sambuc   c->f(p); // expected-warning{{Use of memory after it is freed}}
114f4a2713aSLionel Sambuc   delete c;
115f4a2713aSLionel Sambuc }
116f4a2713aSLionel Sambuc 
117f4a2713aSLionel Sambuc //--------------------------------------------------------------------
118f4a2713aSLionel Sambuc // Check for intersection with other checkers from MallocChecker.cpp
119f4a2713aSLionel Sambuc // bounded with unix.Malloc
120f4a2713aSLionel Sambuc //--------------------------------------------------------------------
121f4a2713aSLionel Sambuc 
122f4a2713aSLionel Sambuc // new/delete oparators are subjects of cplusplus.NewDelete.
testNewDeleteNoWarn()123f4a2713aSLionel Sambuc void testNewDeleteNoWarn() {
124f4a2713aSLionel Sambuc   int i;
125f4a2713aSLionel Sambuc   delete &i; // no-warning
126f4a2713aSLionel Sambuc 
127f4a2713aSLionel Sambuc   int *p1 = new int;
128f4a2713aSLionel Sambuc   delete ++p1; // no-warning
129f4a2713aSLionel Sambuc 
130f4a2713aSLionel Sambuc   int *p2 = new int;
131f4a2713aSLionel Sambuc   delete p2;
132f4a2713aSLionel Sambuc   delete p2; // no-warning
133f4a2713aSLionel Sambuc 
134f4a2713aSLionel Sambuc   int *p3 = new int; // no-warning
135f4a2713aSLionel Sambuc }
136f4a2713aSLionel Sambuc 
137f4a2713aSLionel Sambuc // unix.Malloc does not know about operators new/delete.
testDeleteMallocked()138f4a2713aSLionel Sambuc void testDeleteMallocked() {
139f4a2713aSLionel Sambuc   int *x = (int *)malloc(sizeof(int));
140f4a2713aSLionel Sambuc   delete x; // FIXME: Shoud detect pointer escape and keep silent after 'delete' is modeled properly.
141f4a2713aSLionel Sambuc } // expected-warning{{Potential leak of memory pointed to by 'x'}}
142f4a2713aSLionel Sambuc 
testDeleteOpAfterFree()143f4a2713aSLionel Sambuc void testDeleteOpAfterFree() {
144f4a2713aSLionel Sambuc   int *p = (int *)malloc(sizeof(int));
145f4a2713aSLionel Sambuc   free(p);
146f4a2713aSLionel Sambuc   operator delete(p); // expected-warning{{Use of memory after it is freed}}
147f4a2713aSLionel Sambuc }
148f4a2713aSLionel Sambuc 
testDeleteAfterFree()149f4a2713aSLionel Sambuc void testDeleteAfterFree() {
150f4a2713aSLionel Sambuc   int *p = (int *)malloc(sizeof(int));
151f4a2713aSLionel Sambuc   free(p);
152f4a2713aSLionel Sambuc   delete p; // expected-warning{{Use of memory after it is freed}}
153f4a2713aSLionel Sambuc }
154f4a2713aSLionel Sambuc 
testStandardPlacementNewAfterFree()155f4a2713aSLionel Sambuc void testStandardPlacementNewAfterFree() {
156f4a2713aSLionel Sambuc   int *p = (int *)malloc(sizeof(int));
157f4a2713aSLionel Sambuc   free(p);
158f4a2713aSLionel Sambuc   p = new(p) int; // expected-warning{{Use of memory after it is freed}}
159f4a2713aSLionel Sambuc }
160f4a2713aSLionel Sambuc 
testCustomPlacementNewAfterFree()161f4a2713aSLionel Sambuc void testCustomPlacementNewAfterFree() {
162f4a2713aSLionel Sambuc   int *p = (int *)malloc(sizeof(int));
163f4a2713aSLionel Sambuc   free(p);
164f4a2713aSLionel Sambuc   p = new(0, p) int; // expected-warning{{Use of memory after it is freed}}
165f4a2713aSLionel Sambuc }
166f4a2713aSLionel Sambuc 
testUsingThisAfterDelete()167f4a2713aSLionel Sambuc void testUsingThisAfterDelete() {
168f4a2713aSLionel Sambuc   SomeClass *c = new SomeClass;
169f4a2713aSLionel Sambuc   delete c;
170f4a2713aSLionel Sambuc   c->f(0); // no-warning
171f4a2713aSLionel Sambuc }
172f4a2713aSLionel Sambuc 
testAggregateNew()173f4a2713aSLionel Sambuc void testAggregateNew() {
174f4a2713aSLionel Sambuc   struct Point { int x, y; };
175f4a2713aSLionel Sambuc   new Point{1, 2}; // no crash
176f4a2713aSLionel Sambuc 
177f4a2713aSLionel Sambuc   Point p;
178f4a2713aSLionel Sambuc   new (&p) Point{1, 2}; // no crash
179f4a2713aSLionel Sambuc   clang_analyzer_eval(p.x == 1); // expected-warning{{TRUE}}
180f4a2713aSLionel Sambuc   clang_analyzer_eval(p.y == 2); // expected-warning{{TRUE}}
181f4a2713aSLionel Sambuc }
182f4a2713aSLionel Sambuc 
183f4a2713aSLionel Sambuc //--------------------------------
184f4a2713aSLionel Sambuc // Incorrectly-modelled behavior
185f4a2713aSLionel Sambuc //--------------------------------
186f4a2713aSLionel Sambuc 
testNoInitialization()187f4a2713aSLionel Sambuc int testNoInitialization() {
188f4a2713aSLionel Sambuc   int *n = new int;
189f4a2713aSLionel Sambuc 
190f4a2713aSLionel Sambuc   // Should warn that *n is uninitialized.
191f4a2713aSLionel Sambuc   if (*n) { // no-warning
192f4a2713aSLionel Sambuc     delete n;
193f4a2713aSLionel Sambuc     return 0;
194f4a2713aSLionel Sambuc   }
195f4a2713aSLionel Sambuc   delete n;
196f4a2713aSLionel Sambuc   return 1;
197f4a2713aSLionel Sambuc }
198f4a2713aSLionel Sambuc 
testNoInitializationPlacement()199f4a2713aSLionel Sambuc int testNoInitializationPlacement() {
200f4a2713aSLionel Sambuc   int n;
201f4a2713aSLionel Sambuc   new (&n) int;
202f4a2713aSLionel Sambuc 
203f4a2713aSLionel Sambuc   // Should warn that n is uninitialized.
204f4a2713aSLionel Sambuc   if (n) { // no-warning
205f4a2713aSLionel Sambuc     return 0;
206f4a2713aSLionel Sambuc   }
207f4a2713aSLionel Sambuc   return 1;
208f4a2713aSLionel Sambuc }
209f4a2713aSLionel Sambuc 
210f4a2713aSLionel Sambuc // Test modelling destructor call on call to delete
211f4a2713aSLionel Sambuc class IntPair{
212f4a2713aSLionel Sambuc public:
213f4a2713aSLionel Sambuc   int x;
214f4a2713aSLionel Sambuc   int y;
IntPair()215f4a2713aSLionel Sambuc   IntPair() {};
~IntPair()216f4a2713aSLionel Sambuc   ~IntPair() {x = x/y;}; //expected-warning {{Division by zero}}
217f4a2713aSLionel Sambuc };
218f4a2713aSLionel Sambuc 
testCallToDestructor()219f4a2713aSLionel Sambuc void testCallToDestructor() {
220f4a2713aSLionel Sambuc   IntPair *b = new IntPair();
221f4a2713aSLionel Sambuc   b->x = 1;
222f4a2713aSLionel Sambuc   b->y = 0;
223f4a2713aSLionel Sambuc   delete b; // This results in divide by zero in destructor
224f4a2713aSLionel Sambuc }
225f4a2713aSLionel Sambuc 
226f4a2713aSLionel Sambuc // Test Deleting a value that's passed as an argument.
227f4a2713aSLionel Sambuc class DerefClass{
228f4a2713aSLionel Sambuc public:
229f4a2713aSLionel Sambuc   int *x;
DerefClass()230f4a2713aSLionel Sambuc   DerefClass() {};
~DerefClass()231f4a2713aSLionel Sambuc   ~DerefClass() {*x = 1;}; //expected-warning {{Dereference of null pointer (loaded from field 'x')}}
232f4a2713aSLionel Sambuc };
233f4a2713aSLionel Sambuc 
testDestCall(DerefClass * arg)234f4a2713aSLionel Sambuc void testDestCall(DerefClass *arg) {
235f4a2713aSLionel Sambuc   delete arg;
236f4a2713aSLionel Sambuc }
237f4a2713aSLionel Sambuc 
test_delete_dtor_Arg()238f4a2713aSLionel Sambuc void test_delete_dtor_Arg() {
239f4a2713aSLionel Sambuc   DerefClass *pair = new DerefClass();
240f4a2713aSLionel Sambuc   pair->x = 0;
241f4a2713aSLionel Sambuc   testDestCall(pair);
242f4a2713aSLionel Sambuc }
243f4a2713aSLionel Sambuc 
244f4a2713aSLionel Sambuc //Deleting the address of a local variable, null pointer
245f4a2713aSLionel Sambuc void abort(void) __attribute__((noreturn));
246f4a2713aSLionel Sambuc 
247f4a2713aSLionel Sambuc class NoReturnDtor {
248f4a2713aSLionel Sambuc public:
NoReturnDtor()249f4a2713aSLionel Sambuc   NoReturnDtor() {}
~NoReturnDtor()250f4a2713aSLionel Sambuc   ~NoReturnDtor() {abort();}
251f4a2713aSLionel Sambuc };
252f4a2713aSLionel Sambuc 
test_delete_dtor_LocalVar()253f4a2713aSLionel Sambuc void test_delete_dtor_LocalVar() {
254f4a2713aSLionel Sambuc   NoReturnDtor test;
255f4a2713aSLionel Sambuc   delete &test; // no warn or crash
256f4a2713aSLionel Sambuc }
257f4a2713aSLionel Sambuc 
258f4a2713aSLionel Sambuc class DerivedNoReturn:public NoReturnDtor {
259f4a2713aSLionel Sambuc public:
DerivedNoReturn()260f4a2713aSLionel Sambuc   DerivedNoReturn() {};
~DerivedNoReturn()261f4a2713aSLionel Sambuc   ~DerivedNoReturn() {};
262f4a2713aSLionel Sambuc };
263f4a2713aSLionel Sambuc 
testNullDtorDerived()264f4a2713aSLionel Sambuc void testNullDtorDerived() {
265f4a2713aSLionel Sambuc   DerivedNoReturn *p = new DerivedNoReturn();
266f4a2713aSLionel Sambuc   delete p; // Calls the base destructor which aborts, checked below
267f4a2713aSLionel Sambuc   clang_analyzer_eval(true); // no warn
268f4a2713aSLionel Sambuc }
269f4a2713aSLionel Sambuc 
270*0a6a1f1dSLionel Sambuc //Deleting a non-class pointer should not crash/warn
test_var_delete()271f4a2713aSLionel Sambuc void test_var_delete() {
272f4a2713aSLionel Sambuc   int *v = new int;
273f4a2713aSLionel Sambuc   delete v;  // no crash/warn
274f4a2713aSLionel Sambuc   clang_analyzer_eval(true); // expected-warning{{TRUE}}
275f4a2713aSLionel Sambuc }
276f4a2713aSLionel Sambuc 
testDeleteNull()277f4a2713aSLionel Sambuc void testDeleteNull() {
278f4a2713aSLionel Sambuc   NoReturnDtor *foo = 0;
279f4a2713aSLionel Sambuc   delete foo; // should not call destructor, checked below
280f4a2713aSLionel Sambuc   clang_analyzer_eval(true); // expected-warning{{TRUE}}
281f4a2713aSLionel Sambuc }
282f4a2713aSLionel Sambuc 
testNullAssigneddtor()283f4a2713aSLionel Sambuc void testNullAssigneddtor() {
284f4a2713aSLionel Sambuc   NoReturnDtor *p = 0;
285f4a2713aSLionel Sambuc   NoReturnDtor *s = p;
286f4a2713aSLionel Sambuc   delete s; // should not call destructor, checked below
287f4a2713aSLionel Sambuc   clang_analyzer_eval(true); // expected-warning{{TRUE}}
288f4a2713aSLionel Sambuc }
289f4a2713aSLionel Sambuc 
deleteArg(NoReturnDtor * test)290f4a2713aSLionel Sambuc void deleteArg(NoReturnDtor *test) {
291f4a2713aSLionel Sambuc   delete test;
292f4a2713aSLionel Sambuc }
293f4a2713aSLionel Sambuc 
testNulldtorArg()294f4a2713aSLionel Sambuc void testNulldtorArg() {
295f4a2713aSLionel Sambuc   NoReturnDtor *p = 0;
296f4a2713aSLionel Sambuc   deleteArg(p);
297f4a2713aSLionel Sambuc   clang_analyzer_eval(true); // expected-warning{{TRUE}}
298f4a2713aSLionel Sambuc }
299f4a2713aSLionel Sambuc 
testDeleteUnknown(NoReturnDtor * foo)300f4a2713aSLionel Sambuc void testDeleteUnknown(NoReturnDtor *foo) {
301f4a2713aSLionel Sambuc   delete foo; // should assume non-null and call noreturn destructor
302f4a2713aSLionel Sambuc   clang_analyzer_eval(true); // no-warning
303f4a2713aSLionel Sambuc }
304f4a2713aSLionel Sambuc 
testArrayNull()305f4a2713aSLionel Sambuc void testArrayNull() {
306f4a2713aSLionel Sambuc   NoReturnDtor *fooArray = 0;
307f4a2713aSLionel Sambuc   delete[] fooArray; // should not call destructor, checked below
308f4a2713aSLionel Sambuc   clang_analyzer_eval(true); // expected-warning{{TRUE}}
309f4a2713aSLionel Sambuc }
310f4a2713aSLionel Sambuc 
testArrayDestr()311f4a2713aSLionel Sambuc void testArrayDestr() {
312f4a2713aSLionel Sambuc   NoReturnDtor *p = new NoReturnDtor[2];
313f4a2713aSLionel Sambuc   delete[] p; // Calls the base destructor which aborts, checked below
314f4a2713aSLionel Sambuc   //TODO: clang_analyzer_eval should not be called
315f4a2713aSLionel Sambuc   clang_analyzer_eval(true); // expected-warning{{TRUE}}
316f4a2713aSLionel Sambuc }
317f4a2713aSLionel Sambuc 
318f4a2713aSLionel Sambuc // Invalidate Region even in case of default destructor
319f4a2713aSLionel Sambuc class InvalidateDestTest {
320f4a2713aSLionel Sambuc public:
321f4a2713aSLionel Sambuc   int x;
322f4a2713aSLionel Sambuc   int *y;
323f4a2713aSLionel Sambuc   ~InvalidateDestTest();
324f4a2713aSLionel Sambuc };
325f4a2713aSLionel Sambuc 
test_member_invalidation()326f4a2713aSLionel Sambuc int test_member_invalidation() {
327f4a2713aSLionel Sambuc 
328f4a2713aSLionel Sambuc   //test invalidation of member variable
329f4a2713aSLionel Sambuc   InvalidateDestTest *test = new InvalidateDestTest();
330f4a2713aSLionel Sambuc   test->x = 5;
331f4a2713aSLionel Sambuc   int *k = &(test->x);
332f4a2713aSLionel Sambuc   clang_analyzer_eval(*k == 5); // expected-warning{{TRUE}}
333f4a2713aSLionel Sambuc   delete test;
334f4a2713aSLionel Sambuc   clang_analyzer_eval(*k == 5); // expected-warning{{UNKNOWN}}
335f4a2713aSLionel Sambuc 
336f4a2713aSLionel Sambuc   //test invalidation of member pointer
337f4a2713aSLionel Sambuc   int localVar = 5;
338f4a2713aSLionel Sambuc   test = new InvalidateDestTest();
339f4a2713aSLionel Sambuc   test->y = &localVar;
340f4a2713aSLionel Sambuc   delete test;
341f4a2713aSLionel Sambuc   clang_analyzer_eval(localVar == 5); // expected-warning{{UNKNOWN}}
342f4a2713aSLionel Sambuc 
343f4a2713aSLionel Sambuc   // Test aray elements are invalidated.
344f4a2713aSLionel Sambuc   int Var1 = 5;
345f4a2713aSLionel Sambuc   int Var2 = 5;
346f4a2713aSLionel Sambuc   InvalidateDestTest *a = new InvalidateDestTest[2];
347f4a2713aSLionel Sambuc   a[0].y = &Var1;
348f4a2713aSLionel Sambuc   a[1].y = &Var2;
349f4a2713aSLionel Sambuc   delete[] a;
350f4a2713aSLionel Sambuc   clang_analyzer_eval(Var1 == 5); // expected-warning{{UNKNOWN}}
351f4a2713aSLionel Sambuc   clang_analyzer_eval(Var2 == 5); // expected-warning{{UNKNOWN}}
352f4a2713aSLionel Sambuc   return 0;
353f4a2713aSLionel Sambuc }
354