xref: /llvm-project/clang/test/Analysis/dtor-array.cpp (revision 2fb3bec932ede7704724abb71e8270e0b4c201f6)
1aac73a31Sisuckatcs // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config c++-inlining=destructors -verify -std=c++11 %s
2aac73a31Sisuckatcs // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config c++-inlining=destructors -verify -std=c++17 %s
3aac73a31Sisuckatcs 
4aac73a31Sisuckatcs using size_t =  __typeof(sizeof(int));
5aac73a31Sisuckatcs 
6aac73a31Sisuckatcs void clang_analyzer_eval(bool);
7aac73a31Sisuckatcs void clang_analyzer_checkInlined(bool);
8aac73a31Sisuckatcs void clang_analyzer_warnIfReached();
9aac73a31Sisuckatcs void clang_analyzer_explain(int);
10aac73a31Sisuckatcs 
11aac73a31Sisuckatcs int a, b, c, d;
12aac73a31Sisuckatcs 
13aac73a31Sisuckatcs struct InlineDtor {
14aac73a31Sisuckatcs   static int cnt;
15aac73a31Sisuckatcs   static int dtorCalled;
~InlineDtorInlineDtor16aac73a31Sisuckatcs   ~InlineDtor() {
17aac73a31Sisuckatcs     switch (dtorCalled % 4) {
18aac73a31Sisuckatcs     case 0:
19aac73a31Sisuckatcs       a = cnt++;
20aac73a31Sisuckatcs       break;
21aac73a31Sisuckatcs     case 1:
22aac73a31Sisuckatcs       b = cnt++;
23aac73a31Sisuckatcs       break;
24aac73a31Sisuckatcs     case 2:
25aac73a31Sisuckatcs       c = cnt++;
26aac73a31Sisuckatcs       break;
27aac73a31Sisuckatcs     case 3:
28aac73a31Sisuckatcs       d = cnt++;
29aac73a31Sisuckatcs       break;
30aac73a31Sisuckatcs     }
31aac73a31Sisuckatcs 
32aac73a31Sisuckatcs     ++dtorCalled;
33aac73a31Sisuckatcs   }
34aac73a31Sisuckatcs };
35aac73a31Sisuckatcs 
36aac73a31Sisuckatcs int InlineDtor::cnt = 0;
37aac73a31Sisuckatcs int InlineDtor::dtorCalled = 0;
38aac73a31Sisuckatcs 
foo()39aac73a31Sisuckatcs void foo() {
40aac73a31Sisuckatcs   InlineDtor::cnt = 0;
41aac73a31Sisuckatcs   InlineDtor::dtorCalled = 0;
42aac73a31Sisuckatcs   InlineDtor arr[4];
43aac73a31Sisuckatcs }
44aac73a31Sisuckatcs 
testAutoDtor()45aac73a31Sisuckatcs void testAutoDtor() {
46aac73a31Sisuckatcs   foo();
47aac73a31Sisuckatcs 
48aac73a31Sisuckatcs   clang_analyzer_eval(a == 0); // expected-warning {{TRUE}}
49aac73a31Sisuckatcs   clang_analyzer_eval(b == 1); // expected-warning {{TRUE}}
50aac73a31Sisuckatcs   clang_analyzer_eval(c == 2); // expected-warning {{TRUE}}
51aac73a31Sisuckatcs   clang_analyzer_eval(d == 3); // expected-warning {{TRUE}}
52aac73a31Sisuckatcs }
53aac73a31Sisuckatcs 
testDeleteDtor()54aac73a31Sisuckatcs void testDeleteDtor() {
55aac73a31Sisuckatcs   InlineDtor::cnt = 10;
56aac73a31Sisuckatcs   InlineDtor::dtorCalled = 0;
57aac73a31Sisuckatcs 
58aac73a31Sisuckatcs   InlineDtor *arr = new InlineDtor[4];
59aac73a31Sisuckatcs   delete[] arr;
60aac73a31Sisuckatcs 
61aac73a31Sisuckatcs   clang_analyzer_eval(a == 10); // expected-warning {{TRUE}}
62aac73a31Sisuckatcs   clang_analyzer_eval(b == 11); // expected-warning {{TRUE}}
63aac73a31Sisuckatcs   clang_analyzer_eval(c == 12); // expected-warning {{TRUE}}
64aac73a31Sisuckatcs   clang_analyzer_eval(d == 13); // expected-warning {{TRUE}}
65aac73a31Sisuckatcs }
66aac73a31Sisuckatcs 
67aac73a31Sisuckatcs struct MemberDtor {
68aac73a31Sisuckatcs   InlineDtor arr[4];
69aac73a31Sisuckatcs };
70aac73a31Sisuckatcs 
testMemberDtor()71aac73a31Sisuckatcs void testMemberDtor() {
72aac73a31Sisuckatcs   InlineDtor::cnt = 5;
73aac73a31Sisuckatcs   InlineDtor::dtorCalled = 0;
74aac73a31Sisuckatcs 
75aac73a31Sisuckatcs   MemberDtor *MD = new MemberDtor{};
76aac73a31Sisuckatcs   delete MD;
77aac73a31Sisuckatcs 
78aac73a31Sisuckatcs   clang_analyzer_eval(a == 5); // expected-warning {{TRUE}}
79aac73a31Sisuckatcs   clang_analyzer_eval(b == 6); // expected-warning {{TRUE}}
80aac73a31Sisuckatcs   clang_analyzer_eval(c == 7); // expected-warning {{TRUE}}
81aac73a31Sisuckatcs   clang_analyzer_eval(d == 8); // expected-warning {{TRUE}}
82aac73a31Sisuckatcs }
83aac73a31Sisuckatcs 
84aac73a31Sisuckatcs struct MultipleMemberDtor
85aac73a31Sisuckatcs {
86aac73a31Sisuckatcs   InlineDtor arr[4];
87aac73a31Sisuckatcs   InlineDtor arr2[4];
88aac73a31Sisuckatcs };
89aac73a31Sisuckatcs 
testMultipleMemberDtor()90aac73a31Sisuckatcs void testMultipleMemberDtor() {
91aac73a31Sisuckatcs   InlineDtor::cnt = 30;
92aac73a31Sisuckatcs   InlineDtor::dtorCalled = 0;
93aac73a31Sisuckatcs 
94aac73a31Sisuckatcs   MultipleMemberDtor *MD = new MultipleMemberDtor{};
95aac73a31Sisuckatcs   delete MD;
96aac73a31Sisuckatcs 
97aac73a31Sisuckatcs   clang_analyzer_eval(a == 34); // expected-warning {{TRUE}}
98aac73a31Sisuckatcs   clang_analyzer_eval(b == 35); // expected-warning {{TRUE}}
99aac73a31Sisuckatcs   clang_analyzer_eval(c == 36); // expected-warning {{TRUE}}
100aac73a31Sisuckatcs   clang_analyzer_eval(d == 37); // expected-warning {{TRUE}}
101aac73a31Sisuckatcs }
102aac73a31Sisuckatcs 
103aac73a31Sisuckatcs int EvalOrderArr[4];
104aac73a31Sisuckatcs 
105aac73a31Sisuckatcs struct EvalOrder
106aac73a31Sisuckatcs {
107aac73a31Sisuckatcs   int ctor = 0;
108aac73a31Sisuckatcs   static int dtorCalled;
109aac73a31Sisuckatcs   static int ctorCalled;
110aac73a31Sisuckatcs 
EvalOrderEvalOrder111aac73a31Sisuckatcs   EvalOrder() { ctor = ctorCalled++; };
112aac73a31Sisuckatcs 
~EvalOrderEvalOrder113aac73a31Sisuckatcs   ~EvalOrder() { EvalOrderArr[ctor] = dtorCalled++; }
114aac73a31Sisuckatcs };
115aac73a31Sisuckatcs 
116aac73a31Sisuckatcs int EvalOrder::ctorCalled = 0;
117aac73a31Sisuckatcs int EvalOrder::dtorCalled = 0;
118aac73a31Sisuckatcs 
dtorEvaluationOrder()119aac73a31Sisuckatcs void dtorEvaluationOrder() {
120aac73a31Sisuckatcs   EvalOrder::ctorCalled = 0;
121aac73a31Sisuckatcs   EvalOrder::dtorCalled = 0;
122aac73a31Sisuckatcs 
123aac73a31Sisuckatcs   EvalOrder* eptr = new EvalOrder[4];
124aac73a31Sisuckatcs   delete[] eptr;
125aac73a31Sisuckatcs 
126aac73a31Sisuckatcs   clang_analyzer_eval(EvalOrder::dtorCalled == 4); // expected-warning {{TRUE}}
127aac73a31Sisuckatcs   clang_analyzer_eval(EvalOrder::dtorCalled == EvalOrder::ctorCalled); // expected-warning {{TRUE}}
128aac73a31Sisuckatcs 
129aac73a31Sisuckatcs   clang_analyzer_eval(EvalOrderArr[0] == 3); // expected-warning {{TRUE}}
130aac73a31Sisuckatcs   clang_analyzer_eval(EvalOrderArr[1] == 2); // expected-warning {{TRUE}}
131aac73a31Sisuckatcs   clang_analyzer_eval(EvalOrderArr[2] == 1); // expected-warning {{TRUE}}
132aac73a31Sisuckatcs   clang_analyzer_eval(EvalOrderArr[3] == 0); // expected-warning {{TRUE}}
133aac73a31Sisuckatcs }
134aac73a31Sisuckatcs 
135aac73a31Sisuckatcs struct EmptyDtor {
~EmptyDtorEmptyDtor136aac73a31Sisuckatcs   ~EmptyDtor(){};
137aac73a31Sisuckatcs };
138aac73a31Sisuckatcs 
139aac73a31Sisuckatcs struct DefaultDtor {
140aac73a31Sisuckatcs   ~DefaultDtor() = default;
141aac73a31Sisuckatcs };
142aac73a31Sisuckatcs 
143aac73a31Sisuckatcs // This function used to fail on an assertion.
no_crash()144aac73a31Sisuckatcs void no_crash() {
145aac73a31Sisuckatcs   EmptyDtor* eptr = new EmptyDtor[4];
146aac73a31Sisuckatcs   delete[] eptr;
147aac73a31Sisuckatcs   clang_analyzer_warnIfReached();  // expected-warning{{REACHABLE}}
148aac73a31Sisuckatcs 
149aac73a31Sisuckatcs   DefaultDtor* dptr = new DefaultDtor[4];
150aac73a31Sisuckatcs   delete[] dptr;
151aac73a31Sisuckatcs   clang_analyzer_warnIfReached();  // expected-warning{{REACHABLE}}
152aac73a31Sisuckatcs }
153aac73a31Sisuckatcs 
154aac73a31Sisuckatcs // This snippet used to crash.
155aac73a31Sisuckatcs namespace crash2
156aac73a31Sisuckatcs {
157aac73a31Sisuckatcs   template <class _Tp> class unique_ptr {
158aac73a31Sisuckatcs   typedef _Tp *pointer;
159aac73a31Sisuckatcs   pointer __ptr_;
160aac73a31Sisuckatcs 
161aac73a31Sisuckatcs public:
unique_ptr(pointer __p)162aac73a31Sisuckatcs   unique_ptr(pointer __p) : __ptr_(__p) {}
~unique_ptr()163aac73a31Sisuckatcs   ~unique_ptr() { reset(); }
get()164aac73a31Sisuckatcs   pointer get() { return __ptr_;}
reset()165aac73a31Sisuckatcs   void reset() {}
166aac73a31Sisuckatcs };
167aac73a31Sisuckatcs 
168aac73a31Sisuckatcs struct S;
169aac73a31Sisuckatcs 
170aac73a31Sisuckatcs S *makeS();
171aac73a31Sisuckatcs int bar(S *x, S *y);
172aac73a31Sisuckatcs 
foo()173aac73a31Sisuckatcs void foo() {
174aac73a31Sisuckatcs   unique_ptr<S> x(makeS()), y(makeS());
175aac73a31Sisuckatcs   bar(x.get(), y.get());
176aac73a31Sisuckatcs }
177aac73a31Sisuckatcs 
bar()178aac73a31Sisuckatcs void bar() {
179aac73a31Sisuckatcs   foo();
180aac73a31Sisuckatcs   clang_analyzer_warnIfReached();  // expected-warning{{REACHABLE}}
181aac73a31Sisuckatcs }
182aac73a31Sisuckatcs 
183aac73a31Sisuckatcs } // namespace crash2
184aac73a31Sisuckatcs 
185aac73a31Sisuckatcs // This snippet used to crash.
186aac73a31Sisuckatcs namespace crash3
187aac73a31Sisuckatcs {
188aac73a31Sisuckatcs struct InlineDtor {
~InlineDtorcrash3::InlineDtor189aac73a31Sisuckatcs   ~InlineDtor() {}
190aac73a31Sisuckatcs };
191aac73a31Sisuckatcs struct MultipleMemberDtor
192aac73a31Sisuckatcs {
193aac73a31Sisuckatcs   InlineDtor arr[4];
194aac73a31Sisuckatcs   InlineDtor arr2[4];
195aac73a31Sisuckatcs };
196aac73a31Sisuckatcs 
foo()197aac73a31Sisuckatcs void foo(){
198aac73a31Sisuckatcs   auto *arr = new MultipleMemberDtor[4];
199aac73a31Sisuckatcs   delete[] arr;
200aac73a31Sisuckatcs   clang_analyzer_warnIfReached();  // expected-warning{{REACHABLE}}
201aac73a31Sisuckatcs }
202aac73a31Sisuckatcs } // namespace crash3
203aac73a31Sisuckatcs 
204aac73a31Sisuckatcs namespace crash4 {
205aac73a31Sisuckatcs struct a {
206aac73a31Sisuckatcs   a *b;
207aac73a31Sisuckatcs };
208aac73a31Sisuckatcs struct c {
209aac73a31Sisuckatcs   a d;
210aac73a31Sisuckatcs   c();
~ccrash4::c211aac73a31Sisuckatcs   ~c() {
212aac73a31Sisuckatcs     for (a e = d;; e = *e.b)
213aac73a31Sisuckatcs       ;
214aac73a31Sisuckatcs   }
215aac73a31Sisuckatcs };
f()216aac73a31Sisuckatcs void f() {
217aac73a31Sisuckatcs   c g;
218aac73a31Sisuckatcs   clang_analyzer_warnIfReached();  // expected-warning{{REACHABLE}}
219aac73a31Sisuckatcs }
220aac73a31Sisuckatcs 
221aac73a31Sisuckatcs } // namespace crash4
222aac73a31Sisuckatcs 
223aac73a31Sisuckatcs namespace crash5 {
224aac73a31Sisuckatcs namespace std {
225aac73a31Sisuckatcs template <class _Tp> class unique_ptr {
226aac73a31Sisuckatcs   _Tp *__ptr_;
227aac73a31Sisuckatcs public:
unique_ptr(_Tp * __p)228aac73a31Sisuckatcs   unique_ptr(_Tp *__p) : __ptr_(__p) {}
~unique_ptr()229aac73a31Sisuckatcs   ~unique_ptr() {}
230aac73a31Sisuckatcs };
231aac73a31Sisuckatcs } // namespace std
232aac73a31Sisuckatcs 
SSL_use_certificate(int * arg)233aac73a31Sisuckatcs int SSL_use_certificate(int *arg) {
234aac73a31Sisuckatcs   std::unique_ptr<int> free_x509(arg);
235aac73a31Sisuckatcs   {
236aac73a31Sisuckatcs     if (SSL_use_certificate(arg)) {
237aac73a31Sisuckatcs       return 0;
238aac73a31Sisuckatcs     }
239aac73a31Sisuckatcs   }
240aac73a31Sisuckatcs   clang_analyzer_warnIfReached();  // expected-warning{{REACHABLE}}
241aac73a31Sisuckatcs   return 1;
242aac73a31Sisuckatcs }
243aac73a31Sisuckatcs 
244aac73a31Sisuckatcs } // namespace crash5
245aac73a31Sisuckatcs 
zeroLength()246aac73a31Sisuckatcs void zeroLength(){
247aac73a31Sisuckatcs   InlineDtor::dtorCalled = 0;
248aac73a31Sisuckatcs 
249aac73a31Sisuckatcs   auto *arr = new InlineDtor[0];
250aac73a31Sisuckatcs   delete[] arr;
251aac73a31Sisuckatcs 
252aac73a31Sisuckatcs   auto *arr2 = new InlineDtor[2][0][2];
253aac73a31Sisuckatcs   delete[] arr2;
254aac73a31Sisuckatcs 
255aac73a31Sisuckatcs   auto *arr3 = new InlineDtor[0][2][2];
256aac73a31Sisuckatcs   delete[] arr3;
257aac73a31Sisuckatcs 
258aac73a31Sisuckatcs   auto *arr4 = new InlineDtor[2][2][0];
259aac73a31Sisuckatcs   delete[] arr4;
260aac73a31Sisuckatcs 
261e3e9082bSisuckatcs   clang_analyzer_eval(InlineDtor::dtorCalled == 0); // expected-warning {{TRUE}}
262aac73a31Sisuckatcs }
263aac73a31Sisuckatcs 
264aac73a31Sisuckatcs 
evalOrderPrep()265aac73a31Sisuckatcs void evalOrderPrep() {
266aac73a31Sisuckatcs   EvalOrderArr[0] = 0;
267aac73a31Sisuckatcs   EvalOrderArr[1] = 0;
268aac73a31Sisuckatcs   EvalOrderArr[2] = 0;
269aac73a31Sisuckatcs   EvalOrderArr[3] = 0;
270aac73a31Sisuckatcs 
271aac73a31Sisuckatcs   EvalOrder::ctorCalled = 0;
272aac73a31Sisuckatcs   EvalOrder::dtorCalled = 0;
273aac73a31Sisuckatcs }
274aac73a31Sisuckatcs 
multidimensionalPrep()275aac73a31Sisuckatcs void multidimensionalPrep(){
276aac73a31Sisuckatcs   EvalOrder::ctorCalled = 0;
277aac73a31Sisuckatcs   EvalOrder::dtorCalled = 0;
278aac73a31Sisuckatcs 
279aac73a31Sisuckatcs   EvalOrder arr[2][2];
280aac73a31Sisuckatcs }
281aac73a31Sisuckatcs 
multidimensional()282aac73a31Sisuckatcs void multidimensional(){
283aac73a31Sisuckatcs   evalOrderPrep();
284aac73a31Sisuckatcs   multidimensionalPrep();
285aac73a31Sisuckatcs 
286aac73a31Sisuckatcs   clang_analyzer_eval(EvalOrder::dtorCalled == 4); // expected-warning {{TRUE}}
287aac73a31Sisuckatcs   clang_analyzer_eval(EvalOrder::dtorCalled == EvalOrder::ctorCalled); // expected-warning {{TRUE}}
288aac73a31Sisuckatcs 
289aac73a31Sisuckatcs   clang_analyzer_eval(EvalOrderArr[0] == 3); // expected-warning {{TRUE}}
290aac73a31Sisuckatcs   clang_analyzer_eval(EvalOrderArr[1] == 2); // expected-warning {{TRUE}}
291aac73a31Sisuckatcs   clang_analyzer_eval(EvalOrderArr[2] == 1); // expected-warning {{TRUE}}
292aac73a31Sisuckatcs   clang_analyzer_eval(EvalOrderArr[3] == 0); // expected-warning {{TRUE}}
293aac73a31Sisuckatcs }
294aac73a31Sisuckatcs 
multidimensionalHeap()295aac73a31Sisuckatcs void multidimensionalHeap() {
296aac73a31Sisuckatcs   evalOrderPrep();
297aac73a31Sisuckatcs 
298aac73a31Sisuckatcs   auto* eptr = new EvalOrder[2][2];
299aac73a31Sisuckatcs   delete[] eptr;
300aac73a31Sisuckatcs 
301aac73a31Sisuckatcs   clang_analyzer_eval(EvalOrder::dtorCalled == 4); // expected-warning {{TRUE}}
302aac73a31Sisuckatcs   clang_analyzer_eval(EvalOrder::dtorCalled == EvalOrder::ctorCalled); // expected-warning {{TRUE}}
303aac73a31Sisuckatcs 
304aac73a31Sisuckatcs   clang_analyzer_eval(EvalOrderArr[0] == 3); // expected-warning {{TRUE}}
305aac73a31Sisuckatcs   clang_analyzer_eval(EvalOrderArr[1] == 2); // expected-warning {{TRUE}}
306aac73a31Sisuckatcs   clang_analyzer_eval(EvalOrderArr[2] == 1); // expected-warning {{TRUE}}
307aac73a31Sisuckatcs   clang_analyzer_eval(EvalOrderArr[3] == 0); // expected-warning {{TRUE}}
308aac73a31Sisuckatcs }
309aac73a31Sisuckatcs 
310aac73a31Sisuckatcs struct MultiWrapper{
311aac73a31Sisuckatcs   EvalOrder arr[2][2];
312aac73a31Sisuckatcs };
313aac73a31Sisuckatcs 
multidimensionalMember()314aac73a31Sisuckatcs void multidimensionalMember(){
315aac73a31Sisuckatcs   evalOrderPrep();
316aac73a31Sisuckatcs 
317aac73a31Sisuckatcs   auto* mptr = new MultiWrapper;
318aac73a31Sisuckatcs   delete mptr;
319aac73a31Sisuckatcs 
320aac73a31Sisuckatcs   clang_analyzer_eval(EvalOrder::dtorCalled == 4); // expected-warning {{TRUE}}
321aac73a31Sisuckatcs   clang_analyzer_eval(EvalOrder::dtorCalled == EvalOrder::ctorCalled); // expected-warning {{TRUE}}
322aac73a31Sisuckatcs 
323aac73a31Sisuckatcs   clang_analyzer_eval(EvalOrderArr[0] == 3); // expected-warning {{TRUE}}
324aac73a31Sisuckatcs   clang_analyzer_eval(EvalOrderArr[1] == 2); // expected-warning {{TRUE}}
325aac73a31Sisuckatcs   clang_analyzer_eval(EvalOrderArr[2] == 1); // expected-warning {{TRUE}}
326aac73a31Sisuckatcs   clang_analyzer_eval(EvalOrderArr[3] == 0); // expected-warning {{TRUE}}
327aac73a31Sisuckatcs }
328aac73a31Sisuckatcs 
329aac73a31Sisuckatcs void *memset(void *, int, size_t);
330aac73a31Sisuckatcs void clang_analyzer_dumpElementCount(InlineDtor *);
331aac73a31Sisuckatcs 
nonConstantRegionExtent()332aac73a31Sisuckatcs void nonConstantRegionExtent(){
333aac73a31Sisuckatcs 
334aac73a31Sisuckatcs   InlineDtor::dtorCalled = 0;
335aac73a31Sisuckatcs 
336aac73a31Sisuckatcs   int x = 3;
337aac73a31Sisuckatcs   memset(&x, 1, sizeof(x));
338aac73a31Sisuckatcs 
339aac73a31Sisuckatcs   InlineDtor *arr = new InlineDtor[x];
340aac73a31Sisuckatcs   clang_analyzer_dumpElementCount(arr); // expected-warning {{conj_$0}}
341aac73a31Sisuckatcs   delete [] arr;
342aac73a31Sisuckatcs 
343aac73a31Sisuckatcs   //FIXME: This should be TRUE but memset also sets this
344aac73a31Sisuckatcs   // region to a conjured symbol.
345aac73a31Sisuckatcs   clang_analyzer_eval(InlineDtor::dtorCalled == 0); // expected-warning {{TRUE}} expected-warning {{FALSE}}
346aac73a31Sisuckatcs }
347*2fb3bec9STomasz Kamiński 
348*2fb3bec9STomasz Kamiński namespace crash6 {
349*2fb3bec9STomasz Kamiński 
350*2fb3bec9STomasz Kamiński struct NonTrivialItem {
351*2fb3bec9STomasz Kamiński   ~NonTrivialItem();
352*2fb3bec9STomasz Kamiński };
353*2fb3bec9STomasz Kamiński 
354*2fb3bec9STomasz Kamiński struct WeirdVec {
clearcrash6::WeirdVec355*2fb3bec9STomasz Kamiński   void clear() {
356*2fb3bec9STomasz Kamiński     delete[] data;
357*2fb3bec9STomasz Kamiński     size = 0;
358*2fb3bec9STomasz Kamiński   }
359*2fb3bec9STomasz Kamiński   NonTrivialItem *data;
360*2fb3bec9STomasz Kamiński   unsigned size;
361*2fb3bec9STomasz Kamiński };
362*2fb3bec9STomasz Kamiński 
top(int j)363*2fb3bec9STomasz Kamiński void top(int j) {
364*2fb3bec9STomasz Kamiński   WeirdVec *p = new WeirdVec;
365*2fb3bec9STomasz Kamiński 
366*2fb3bec9STomasz Kamiński   p[j].size = 0;
367*2fb3bec9STomasz Kamiński   delete[] p->data; // no-crash
368*2fb3bec9STomasz Kamiński }
369*2fb3bec9STomasz Kamiński 
370*2fb3bec9STomasz Kamiński template <typename T>
make_unknown()371*2fb3bec9STomasz Kamiński T make_unknown() {
372*2fb3bec9STomasz Kamiński   return reinterpret_cast<T>(static_cast<int>(0.404));
373*2fb3bec9STomasz Kamiński }
374*2fb3bec9STomasz Kamiński 
directUnknownSymbol()375*2fb3bec9STomasz Kamiński void directUnknownSymbol() {
376*2fb3bec9STomasz Kamiński   delete[] make_unknown<NonTrivialItem*>(); // no-crash
377*2fb3bec9STomasz Kamiński }
378*2fb3bec9STomasz Kamiński 
379*2fb3bec9STomasz Kamiński }
380