[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / test / Analysis / dtor-array.cpp
blob84a34af92251692e6e6f5ad6ebc1ef4fcb10f098
1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config c++-inlining=destructors -verify -std=c++11 %s
2 // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config c++-inlining=destructors -verify -std=c++17 %s
4 using size_t = __typeof(sizeof(int));
6 void clang_analyzer_eval(bool);
7 void clang_analyzer_checkInlined(bool);
8 void clang_analyzer_warnIfReached();
9 void clang_analyzer_explain(int);
11 int a, b, c, d;
13 struct InlineDtor {
14 static int cnt;
15 static int dtorCalled;
16 ~InlineDtor() {
17 switch (dtorCalled % 4) {
18 case 0:
19 a = cnt++;
20 break;
21 case 1:
22 b = cnt++;
23 break;
24 case 2:
25 c = cnt++;
26 break;
27 case 3:
28 d = cnt++;
29 break;
32 ++dtorCalled;
36 int InlineDtor::cnt = 0;
37 int InlineDtor::dtorCalled = 0;
39 void foo() {
40 InlineDtor::cnt = 0;
41 InlineDtor::dtorCalled = 0;
42 InlineDtor arr[4];
45 void testAutoDtor() {
46 foo();
48 clang_analyzer_eval(a == 0); // expected-warning {{TRUE}}
49 clang_analyzer_eval(b == 1); // expected-warning {{TRUE}}
50 clang_analyzer_eval(c == 2); // expected-warning {{TRUE}}
51 clang_analyzer_eval(d == 3); // expected-warning {{TRUE}}
54 void testDeleteDtor() {
55 InlineDtor::cnt = 10;
56 InlineDtor::dtorCalled = 0;
58 InlineDtor *arr = new InlineDtor[4];
59 delete[] arr;
61 clang_analyzer_eval(a == 10); // expected-warning {{TRUE}}
62 clang_analyzer_eval(b == 11); // expected-warning {{TRUE}}
63 clang_analyzer_eval(c == 12); // expected-warning {{TRUE}}
64 clang_analyzer_eval(d == 13); // expected-warning {{TRUE}}
67 struct MemberDtor {
68 InlineDtor arr[4];
71 void testMemberDtor() {
72 InlineDtor::cnt = 5;
73 InlineDtor::dtorCalled = 0;
75 MemberDtor *MD = new MemberDtor{};
76 delete MD;
78 clang_analyzer_eval(a == 5); // expected-warning {{TRUE}}
79 clang_analyzer_eval(b == 6); // expected-warning {{TRUE}}
80 clang_analyzer_eval(c == 7); // expected-warning {{TRUE}}
81 clang_analyzer_eval(d == 8); // expected-warning {{TRUE}}
84 struct MultipleMemberDtor
86 InlineDtor arr[4];
87 InlineDtor arr2[4];
90 void testMultipleMemberDtor() {
91 InlineDtor::cnt = 30;
92 InlineDtor::dtorCalled = 0;
94 MultipleMemberDtor *MD = new MultipleMemberDtor{};
95 delete MD;
97 clang_analyzer_eval(a == 34); // expected-warning {{TRUE}}
98 clang_analyzer_eval(b == 35); // expected-warning {{TRUE}}
99 clang_analyzer_eval(c == 36); // expected-warning {{TRUE}}
100 clang_analyzer_eval(d == 37); // expected-warning {{TRUE}}
103 int EvalOrderArr[4];
105 struct EvalOrder
107 int ctor = 0;
108 static int dtorCalled;
109 static int ctorCalled;
111 EvalOrder() { ctor = ctorCalled++; };
113 ~EvalOrder() { EvalOrderArr[ctor] = dtorCalled++; }
116 int EvalOrder::ctorCalled = 0;
117 int EvalOrder::dtorCalled = 0;
119 void dtorEvaluationOrder() {
120 EvalOrder::ctorCalled = 0;
121 EvalOrder::dtorCalled = 0;
123 EvalOrder* eptr = new EvalOrder[4];
124 delete[] eptr;
126 clang_analyzer_eval(EvalOrder::dtorCalled == 4); // expected-warning {{TRUE}}
127 clang_analyzer_eval(EvalOrder::dtorCalled == EvalOrder::ctorCalled); // expected-warning {{TRUE}}
129 clang_analyzer_eval(EvalOrderArr[0] == 3); // expected-warning {{TRUE}}
130 clang_analyzer_eval(EvalOrderArr[1] == 2); // expected-warning {{TRUE}}
131 clang_analyzer_eval(EvalOrderArr[2] == 1); // expected-warning {{TRUE}}
132 clang_analyzer_eval(EvalOrderArr[3] == 0); // expected-warning {{TRUE}}
135 struct EmptyDtor {
136 ~EmptyDtor(){};
139 struct DefaultDtor {
140 ~DefaultDtor() = default;
143 // This function used to fail on an assertion.
144 void no_crash() {
145 EmptyDtor* eptr = new EmptyDtor[4];
146 delete[] eptr;
147 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
149 DefaultDtor* dptr = new DefaultDtor[4];
150 delete[] dptr;
151 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
154 // This snippet used to crash.
155 namespace crash2
157 template <class _Tp> class unique_ptr {
158 typedef _Tp *pointer;
159 pointer __ptr_;
161 public:
162 unique_ptr(pointer __p) : __ptr_(__p) {}
163 ~unique_ptr() { reset(); }
164 pointer get() { return __ptr_;}
165 void reset() {}
168 struct S;
170 S *makeS();
171 int bar(S *x, S *y);
173 void foo() {
174 unique_ptr<S> x(makeS()), y(makeS());
175 bar(x.get(), y.get());
178 void bar() {
179 foo();
180 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
183 } // namespace crash2
185 // This snippet used to crash.
186 namespace crash3
188 struct InlineDtor {
189 ~InlineDtor() {}
191 struct MultipleMemberDtor
193 InlineDtor arr[4];
194 InlineDtor arr2[4];
197 void foo(){
198 auto *arr = new MultipleMemberDtor[4];
199 delete[] arr;
200 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
202 } // namespace crash3
204 namespace crash4 {
205 struct a {
206 a *b;
208 struct c {
209 a d;
210 c();
211 ~c() {
212 for (a e = d;; e = *e.b)
216 void f() {
217 c g;
218 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
221 } // namespace crash4
223 namespace crash5 {
224 namespace std {
225 template <class _Tp> class unique_ptr {
226 _Tp *__ptr_;
227 public:
228 unique_ptr(_Tp *__p) : __ptr_(__p) {}
229 ~unique_ptr() {}
231 } // namespace std
233 int SSL_use_certificate(int *arg) {
234 std::unique_ptr<int> free_x509(arg);
236 if (SSL_use_certificate(arg)) {
237 return 0;
240 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
241 return 1;
244 } // namespace crash5
246 void zeroLength(){
247 InlineDtor::dtorCalled = 0;
249 auto *arr = new InlineDtor[0];
250 delete[] arr;
252 auto *arr2 = new InlineDtor[2][0][2];
253 delete[] arr2;
255 auto *arr3 = new InlineDtor[0][2][2];
256 delete[] arr3;
258 auto *arr4 = new InlineDtor[2][2][0];
259 delete[] arr4;
261 clang_analyzer_eval(InlineDtor::dtorCalled == 0); // expected-warning {{TRUE}}
265 void evalOrderPrep() {
266 EvalOrderArr[0] = 0;
267 EvalOrderArr[1] = 0;
268 EvalOrderArr[2] = 0;
269 EvalOrderArr[3] = 0;
271 EvalOrder::ctorCalled = 0;
272 EvalOrder::dtorCalled = 0;
275 void multidimensionalPrep(){
276 EvalOrder::ctorCalled = 0;
277 EvalOrder::dtorCalled = 0;
279 EvalOrder arr[2][2];
282 void multidimensional(){
283 evalOrderPrep();
284 multidimensionalPrep();
286 clang_analyzer_eval(EvalOrder::dtorCalled == 4); // expected-warning {{TRUE}}
287 clang_analyzer_eval(EvalOrder::dtorCalled == EvalOrder::ctorCalled); // expected-warning {{TRUE}}
289 clang_analyzer_eval(EvalOrderArr[0] == 3); // expected-warning {{TRUE}}
290 clang_analyzer_eval(EvalOrderArr[1] == 2); // expected-warning {{TRUE}}
291 clang_analyzer_eval(EvalOrderArr[2] == 1); // expected-warning {{TRUE}}
292 clang_analyzer_eval(EvalOrderArr[3] == 0); // expected-warning {{TRUE}}
295 void multidimensionalHeap() {
296 evalOrderPrep();
298 auto* eptr = new EvalOrder[2][2];
299 delete[] eptr;
301 clang_analyzer_eval(EvalOrder::dtorCalled == 4); // expected-warning {{TRUE}}
302 clang_analyzer_eval(EvalOrder::dtorCalled == EvalOrder::ctorCalled); // expected-warning {{TRUE}}
304 clang_analyzer_eval(EvalOrderArr[0] == 3); // expected-warning {{TRUE}}
305 clang_analyzer_eval(EvalOrderArr[1] == 2); // expected-warning {{TRUE}}
306 clang_analyzer_eval(EvalOrderArr[2] == 1); // expected-warning {{TRUE}}
307 clang_analyzer_eval(EvalOrderArr[3] == 0); // expected-warning {{TRUE}}
310 struct MultiWrapper{
311 EvalOrder arr[2][2];
314 void multidimensionalMember(){
315 evalOrderPrep();
317 auto* mptr = new MultiWrapper;
318 delete mptr;
320 clang_analyzer_eval(EvalOrder::dtorCalled == 4); // expected-warning {{TRUE}}
321 clang_analyzer_eval(EvalOrder::dtorCalled == EvalOrder::ctorCalled); // expected-warning {{TRUE}}
323 clang_analyzer_eval(EvalOrderArr[0] == 3); // expected-warning {{TRUE}}
324 clang_analyzer_eval(EvalOrderArr[1] == 2); // expected-warning {{TRUE}}
325 clang_analyzer_eval(EvalOrderArr[2] == 1); // expected-warning {{TRUE}}
326 clang_analyzer_eval(EvalOrderArr[3] == 0); // expected-warning {{TRUE}}
329 void *memset(void *, int, size_t);
330 void clang_analyzer_dumpElementCount(InlineDtor *);
332 void nonConstantRegionExtent(){
334 InlineDtor::dtorCalled = 0;
336 int x = 3;
337 memset(&x, 1, sizeof(x));
339 InlineDtor *arr = new InlineDtor[x];
340 clang_analyzer_dumpElementCount(arr); // expected-warning {{conj_$0}}
341 delete [] arr;
343 //FIXME: This should be TRUE but memset also sets this
344 // region to a conjured symbol.
345 clang_analyzer_eval(InlineDtor::dtorCalled == 0); // expected-warning {{TRUE}} expected-warning {{FALSE}}
348 namespace crash6 {
350 struct NonTrivialItem {
351 ~NonTrivialItem();
354 struct WeirdVec {
355 void clear() {
356 delete[] data;
357 size = 0;
359 NonTrivialItem *data;
360 unsigned size;
363 void top(int j) {
364 WeirdVec *p = new WeirdVec;
366 p[j].size = 0;
367 delete[] p->data; // no-crash
370 template <typename T>
371 T make_unknown() {
372 return reinterpret_cast<T>(static_cast<int>(0.404));
375 void directUnknownSymbol() {
376 delete[] make_unknown<NonTrivialItem*>(); // no-crash