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);
15 static int dtorCalled
;
17 switch (dtorCalled
% 4) {
36 int InlineDtor::cnt
= 0;
37 int InlineDtor::dtorCalled
= 0;
41 InlineDtor::dtorCalled
= 0;
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() {
56 InlineDtor::dtorCalled
= 0;
58 InlineDtor
*arr
= new InlineDtor
[4];
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}}
71 void testMemberDtor() {
73 InlineDtor::dtorCalled
= 0;
75 MemberDtor
*MD
= new MemberDtor
{};
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
90 void testMultipleMemberDtor() {
92 InlineDtor::dtorCalled
= 0;
94 MultipleMemberDtor
*MD
= new MultipleMemberDtor
{};
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}}
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];
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}}
140 ~DefaultDtor() = default;
143 // This function used to fail on an assertion.
145 EmptyDtor
* eptr
= new EmptyDtor
[4];
147 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
149 DefaultDtor
* dptr
= new DefaultDtor
[4];
151 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
154 // This snippet used to crash.
157 template <class _Tp
> class unique_ptr
{
158 typedef _Tp
*pointer
;
162 unique_ptr(pointer __p
) : __ptr_(__p
) {}
163 ~unique_ptr() { reset(); }
164 pointer
get() { return __ptr_
;}
174 unique_ptr
<S
> x(makeS()), y(makeS());
175 bar(x
.get(), y
.get());
180 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
183 } // namespace crash2
185 // This snippet used to crash.
191 struct MultipleMemberDtor
198 auto *arr
= new MultipleMemberDtor
[4];
200 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
202 } // namespace crash3
212 for (a e
= d
;; e
= *e
.b
)
218 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
221 } // namespace crash4
225 template <class _Tp
> class unique_ptr
{
228 unique_ptr(_Tp
*__p
) : __ptr_(__p
) {}
233 int SSL_use_certificate(int *arg
) {
234 std::unique_ptr
<int> free_x509(arg
);
236 if (SSL_use_certificate(arg
)) {
240 clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
244 } // namespace crash5
247 InlineDtor::dtorCalled
= 0;
249 auto *arr
= new InlineDtor
[0];
252 auto *arr2
= new InlineDtor
[2][0][2];
255 auto *arr3
= new InlineDtor
[0][2][2];
258 auto *arr4
= new InlineDtor
[2][2][0];
261 clang_analyzer_eval(InlineDtor::dtorCalled
== 0); // expected-warning {{TRUE}}
265 void evalOrderPrep() {
271 EvalOrder::ctorCalled
= 0;
272 EvalOrder::dtorCalled
= 0;
275 void multidimensionalPrep(){
276 EvalOrder::ctorCalled
= 0;
277 EvalOrder::dtorCalled
= 0;
282 void multidimensional(){
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() {
298 auto* eptr
= new EvalOrder
[2][2];
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}}
314 void multidimensionalMember(){
317 auto* mptr
= new MultiWrapper
;
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;
337 memset(&x
, 1, sizeof(x
));
339 InlineDtor
*arr
= new InlineDtor
[x
];
340 clang_analyzer_dumpElementCount(arr
); // expected-warning {{conj_$0}}
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}}
350 struct NonTrivialItem
{
359 NonTrivialItem
*data
;
364 WeirdVec
*p
= new WeirdVec
;
367 delete[] p
->data
; // no-crash
370 template <typename T
>
372 return reinterpret_cast<T
>(static_cast<int>(0.404));
375 void directUnknownSymbol() {
376 delete[] make_unknown
<NonTrivialItem
*>(); // no-crash