1 // RUN: rm -f %t.14 %t.2a
2 // RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -std=c++14 -DCXX2A=0 -fblocks -Wall -Wno-unused -Werror %s > %t.14 2>&1
3 // RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -std=c++2a -DCXX2A=1 -fblocks -Wall -Wno-unused -Werror %s > %t.2a 2>&1
4 // RUN: FileCheck --input-file=%t.14 -check-prefixes=CHECK,CXX14 -implicit-check-not=destructor %s
5 // RUN: FileCheck --input-file=%t.2a -check-prefixes=CHECK,CXX2A -implicit-check-not=destructor %s
7 int puts(const char *);
12 // Guarantee that the elided examples are actually elided by deleting the
14 Foo(const Foo
&) = delete;
16 // No elision support, so we need a copy constructor.
33 Bar
&operator=(const Bar
&);
45 void elided_assign() {
48 // CHECK: void elided_assign()
49 // CXX14: (CXXConstructExpr{{.*}}, struct Foo)
50 // CXX14: ~Foo() (Temporary object destructor)
51 // CHECK: ~Foo() (Implicit destructor)
53 void nonelided_assign() {
54 Bar x
= (const Bar
&)get_bar();
56 // CHECK: void nonelided_assign()
57 // CHECK: (CXXConstructExpr{{.*}}, struct Bar)
58 // CHECK: ~Bar() (Temporary object destructor)
59 // CHECK: ~Bar() (Implicit destructor)
61 void elided_paren_init() {
64 // CHECK: void elided_paren_init()
65 // CXX14: (CXXConstructExpr{{.*}}, struct Foo)
66 // CXX14: ~Foo() (Temporary object destructor)
67 // CHECK: ~Foo() (Implicit destructor)
69 void nonelided_paren_init() {
70 Bar
x((const Bar
&)get_bar());
72 // CHECK: void nonelided_paren_init()
73 // CHECK: (CXXConstructExpr{{.*}}, struct Bar)
74 // CHECK: ~Bar() (Temporary object destructor)
75 // CHECK: ~Bar() (Implicit destructor)
77 void elided_brace_init() {
80 // CHECK: void elided_brace_init()
81 // CXX14: (CXXConstructExpr{{.*}}, struct Foo)
82 // CXX14: ~Foo() (Temporary object destructor)
83 // CHECK: ~Foo() (Implicit destructor)
85 void nonelided_brace_init() {
86 Bar x
{(const Bar
&)get_bar()};
88 // CHECK: void nonelided_brace_init()
89 // CHECK: (CXXConstructExpr{{.*}}, struct Bar)
90 // CHECK: ~Bar() (Temporary object destructor)
91 // CHECK: ~Bar() (Implicit destructor)
93 void elided_lambda_capture_init() {
94 // The copy from get_foo() into the lambda should be elided. Should call
95 // the lambda's destructor, but not ~Foo() separately.
96 // (This syntax is C++14 'generalized lambda captures'.)
97 auto z
= [x
=get_foo()]() {};
99 // CHECK: void elided_lambda_capture_init()
100 // CXX14: (CXXConstructExpr{{.*}}, struct Foo)
101 // CXX14: ~(lambda at {{.*}})() (Temporary object destructor)
102 // CXX14: ~Foo() (Temporary object destructor)
103 // CHECK: ~(lambda at {{.*}})() (Implicit destructor)
105 void nonelided_lambda_capture_init() {
106 // Should call the lambda's destructor as well as ~Bar() for the temporary.
107 auto z
= [x((const Bar
&)get_bar())]() {};
109 // CHECK: void nonelided_lambda_capture_init()
110 // CHECK: (CXXConstructExpr{{.*}}, struct Bar)
111 // CXX14: ~(lambda at {{.*}})() (Temporary object destructor)
112 // CHECK: ~Bar() (Temporary object destructor)
113 // CHECK: ~(lambda at {{.*}})() (Implicit destructor)
115 Foo
elided_return_stmt_expr() {
116 // Two copies, both elided in C++17.
117 return ({ get_foo(); });
119 // CHECK: Foo elided_return_stmt_expr()
120 // CXX14: (CXXConstructExpr{{.*}}, struct Foo)
121 // CXX14: ~Foo() (Temporary object destructor)
122 // CXX14: (CXXConstructExpr{{.*}}, struct Foo)
123 // CXX14: ~Foo() (Temporary object destructor)
125 void elided_stmt_expr() {
126 // One copy, elided in C++17.
129 // CHECK: void elided_stmt_expr()
130 // CXX14: (CXXConstructExpr{{.*}}, struct Foo)
131 // CXX14: ~Foo() (Temporary object destructor)
132 // CHECK: ~Foo() (Temporary object destructor)
135 void elided_stmt_expr_multiple_stmts() {
136 // Make sure that only the value returned out of a statement expression is
138 ({ get_bar(); get_foo(); });
140 // CHECK: void elided_stmt_expr_multiple_stmts()
141 // CHECK: ~Bar() (Temporary object destructor)
142 // CXX14: (CXXConstructExpr{{.*}}, struct Foo)
143 // CXX14: ~Foo() (Temporary object destructor)
144 // CHECK: ~Foo() (Temporary object destructor)
147 void unelided_stmt_expr() {
148 ({ (const Bar
&)get_bar(); });
150 // CHECK: void unelided_stmt_expr()
151 // CHECK: (CXXConstructExpr{{.*}}, struct Bar)
152 // CHECK: ~Bar() (Temporary object destructor)
153 // CHECK: ~Bar() (Temporary object destructor)
155 void elided_aggregate_init() {
156 TwoFoos x
{get_foo(), get_foo()};
158 // CHECK: void elided_aggregate_init()
159 // CXX14: (CXXConstructExpr{{.*}}, struct Foo)
160 // CXX14: (CXXConstructExpr{{.*}}, struct Foo)
161 // CXX14: ~Foo() (Temporary object destructor)
162 // CXX14: ~Foo() (Temporary object destructor)
163 // CHECK: ~TwoFoos() (Implicit destructor)
165 void nonelided_aggregate_init() {
166 TwoBars x
{(const Bar
&)get_bar(), (const Bar
&)get_bar()};
168 // CHECK: void nonelided_aggregate_init()
169 // CHECK: (CXXConstructExpr{{.*}}, struct Bar)
170 // CHECK: (CXXConstructExpr{{.*}}, struct Bar)
171 // CHECK: ~Bar() (Temporary object destructor)
172 // CHECK: ~Bar() (Temporary object destructor)
173 // CHECK: ~TwoBars() (Implicit destructor)
175 TwoFoos
return_aggregate_init() {
176 return TwoFoos
{get_foo(), get_foo()};
178 // CHECK: TwoFoos return_aggregate_init()
179 // CXX14: (CXXConstructExpr{{.*}}, struct Foo)
180 // CXX14: (CXXConstructExpr{{.*}}, struct Foo)
181 // CXX14: ~TwoFoos() (Temporary object destructor)
182 // CXX14: ~Foo() (Temporary object destructor)
183 // CXX14: ~Foo() (Temporary object destructor)
185 void lifetime_extended() {
186 const Foo
&x
= (get_foo(), get_foo());
187 puts("one destroyed before, one destroyed after");
189 // CHECK: void lifetime_extended()
190 // CHECK: ~Foo() (Temporary object destructor)
191 // CHECK: one destroyed before, one destroyed after
192 // CHECK: ~Foo() (Implicit destructor)
194 void not_lifetime_extended() {
195 Foo x
= (get_foo(), get_foo());
196 puts("one destroyed before, one destroyed after");
198 // CHECK: void not_lifetime_extended()
199 // CXX14: (CXXConstructExpr{{.*}}, struct Foo)
200 // CHECK: ~Foo() (Temporary object destructor)
201 // CXX14: ~Foo() (Temporary object destructor)
202 // CHECK: one destroyed before, one destroyed after
203 // CHECK: ~Foo() (Implicit destructor)
205 void compound_literal() {
206 (void)(Bar
[]){{}, {}};
208 // CHECK: void compound_literal()
209 // CHECK: (CXXConstructExpr, struct Bar)
210 // CHECK: (CXXConstructExpr, struct Bar)
211 // CHECK: ~Bar[2]() (Temporary object destructor)
213 Foo
elided_return() {
216 // CHECK: Foo elided_return()
217 // CXX14: (CXXConstructExpr{{.*}}, struct Foo)
218 // CXX14: ~Foo() (Temporary object destructor)
220 auto elided_return_lambda() {
221 return [x
=get_foo()]() {};
223 // CHECK: (lambda at {{.*}}) elided_return_lambda()
224 // CXX14: (CXXConstructExpr{{.*}}, class (lambda at {{.*}}))
225 // CXX14: ~(lambda at {{.*}})() (Temporary object destructor)
226 // CXX14: ~Foo() (Temporary object destructor)
228 void const_auto_obj() {
231 // CHECK: void const_auto_obj()
232 // CHECK: .~Bar() (Implicit destructor)
234 void has_default_arg(Foo foo
= get_foo());
235 void test_default_arg() {
236 // FIXME: This emits a destructor but no constructor. Search CFG.cpp for
237 // 'PR13385' for details.
240 // CHECK: void test_default_arg()
241 // CXX14: ~Foo() (Temporary object destructor)
242 // CHECK: ~Foo() (Temporary object destructor)
244 struct DefaultArgInCtor
{
245 DefaultArgInCtor(Foo foo
= get_foo());
249 void default_ctor_with_default_arg() {
250 // FIXME: Default arguments are mishandled in two ways:
251 // - The constructor is not emitted at all (not specific to arrays; see fixme
252 // in CFG.cpp that mentions PR13385).
253 // - The destructor is emitted once, even though the default argument will be
254 // constructed and destructed once per array element.
255 // Ideally, the CFG would expand array constructions into a loop that
256 // constructs each array element, allowing default argument
257 // constructor/destructor calls to be correctly placed inside the loop.
258 DefaultArgInCtor qux
[3];
260 // CHECK: void default_ctor_with_default_arg()
261 // CHECK: CXXConstructExpr, {{.*}}, struct DefaultArgInCtor[3]
262 // CXX14: ~Foo() (Temporary object destructor)
263 // CHECK: ~Foo() (Temporary object destructor)
264 // CHECK: .~DefaultArgInCtor[3]() (Implicit destructor)
266 void new_default_ctor_with_default_arg(long count
) {
267 // Same problems as above.
268 new DefaultArgInCtor
[count
];
270 // CHECK: void new_default_ctor_with_default_arg(long count)
271 // CHECK: CXXConstructExpr, {{.*}}, struct DefaultArgInCtor[]
272 // CXX14: ~Foo() (Temporary object destructor)
273 // CHECK: ~Foo() (Temporary object destructor)
276 // Boilerplate needed to test co_return:
279 template <typename Promise
>
280 struct coroutine_handle
{
281 static coroutine_handle
from_address(void *) noexcept
;
286 TestPromise
initial_suspend();
287 TestPromise
final_suspend() noexcept
;
288 bool await_ready() noexcept
;
289 void await_suspend(const std::coroutine_handle
<TestPromise
> &) noexcept
;
290 void await_resume() noexcept
;
291 Foo
return_value(const Bar
&);
292 Bar
get_return_object();
293 void unhandled_exception();
297 template <typename Ret
, typename
... Args
>
298 struct coroutine_traits
;
300 struct coroutine_traits
<Bar
> {
301 using promise_type
= TestPromise
;
307 // This expands to something like:
308 // promise.return_value(get_bar());
309 // get_bar() is passed by reference to return_value() and is then destroyed;
310 // there is no equivalent of RVO. TestPromise::return_value also returns a
311 // Foo, which should be immediately destroyed.
312 // FIXME: The generated CFG completely ignores get_return_object().
314 // CXX2A: Bar coreturn()
315 // CXX2A: ~Foo() (Temporary object destructor)
316 // CXX2A: ~Bar() (Temporary object destructor)