// RUN: rm -f %t.14 %t.2a
// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -std=c++14 -DCXX2A=0 -fblocks -Wall -Wno-unused -Werror %s > %t.14 2>&1
// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -std=c++2a -DCXX2A=1 -fblocks -Wall -Wno-unused -Werror %s > %t.2a 2>&1
// RUN: FileCheck --input-file=%t.14 -check-prefixes=CHECK,CXX14 -implicit-check-not=destructor %s
// RUN: FileCheck --input-file=%t.2a -check-prefixes=CHECK,CXX2A -implicit-check-not=destructor %s
int ;
;
;
Foo ;
;
Bar ;
;
// Start of tests:
void
// CHECK: void elided_assign()
// CXX14: (CXXConstructExpr{{.*}}, struct Foo)
// CXX14: ~Foo() (Temporary object destructor)
// CHECK: ~Foo() (Implicit destructor)
void
// CHECK: void nonelided_assign()
// CHECK: (CXXConstructExpr{{.*}}, struct Bar)
// CHECK: ~Bar() (Temporary object destructor)
// CHECK: ~Bar() (Implicit destructor)
void
// CHECK: void elided_paren_init()
// CXX14: (CXXConstructExpr{{.*}}, struct Foo)
// CXX14: ~Foo() (Temporary object destructor)
// CHECK: ~Foo() (Implicit destructor)
void
// CHECK: void nonelided_paren_init()
// CHECK: (CXXConstructExpr{{.*}}, struct Bar)
// CHECK: ~Bar() (Temporary object destructor)
// CHECK: ~Bar() (Implicit destructor)
void
// CHECK: void elided_brace_init()
// CXX14: (CXXConstructExpr{{.*}}, struct Foo)
// CXX14: ~Foo() (Temporary object destructor)
// CHECK: ~Foo() (Implicit destructor)
void
// CHECK: void nonelided_brace_init()
// CHECK: (CXXConstructExpr{{.*}}, struct Bar)
// CHECK: ~Bar() (Temporary object destructor)
// CHECK: ~Bar() (Implicit destructor)
void
// CHECK: void elided_lambda_capture_init()
// CXX14: (CXXConstructExpr{{.*}}, struct Foo)
// CXX14: ~(lambda at {{.*}})() (Temporary object destructor)
// CXX14: ~Foo() (Temporary object destructor)
// CHECK: ~(lambda at {{.*}})() (Implicit destructor)
void
// CHECK: void nonelided_lambda_capture_init()
// CHECK: (CXXConstructExpr{{.*}}, struct Bar)
// CXX14: ~(lambda at {{.*}})() (Temporary object destructor)
// CHECK: ~Bar() (Temporary object destructor)
// CHECK: ~(lambda at {{.*}})() (Implicit destructor)
Foo
// CHECK: Foo elided_return_stmt_expr()
// CXX14: (CXXConstructExpr{{.*}}, struct Foo)
// CXX14: ~Foo() (Temporary object destructor)
// CXX14: (CXXConstructExpr{{.*}}, struct Foo)
// CXX14: ~Foo() (Temporary object destructor)
void
// CHECK: void elided_stmt_expr()
// CXX14: (CXXConstructExpr{{.*}}, struct Foo)
// CXX14: ~Foo() (Temporary object destructor)
// CHECK: ~Foo() (Temporary object destructor)
void
// CHECK: void elided_stmt_expr_multiple_stmts()
// CHECK: ~Bar() (Temporary object destructor)
// CXX14: (CXXConstructExpr{{.*}}, struct Foo)
// CXX14: ~Foo() (Temporary object destructor)
// CHECK: ~Foo() (Temporary object destructor)
void
// CHECK: void unelided_stmt_expr()
// CHECK: (CXXConstructExpr{{.*}}, struct Bar)
// CHECK: ~Bar() (Temporary object destructor)
// CHECK: ~Bar() (Temporary object destructor)
void
// CHECK: void elided_aggregate_init()
// CXX14: (CXXConstructExpr{{.*}}, struct Foo)
// CXX14: (CXXConstructExpr{{.*}}, struct Foo)
// CXX14: ~Foo() (Temporary object destructor)
// CXX14: ~Foo() (Temporary object destructor)
// CHECK: ~TwoFoos() (Implicit destructor)
void
// CHECK: void nonelided_aggregate_init()
// CHECK: (CXXConstructExpr{{.*}}, struct Bar)
// CHECK: (CXXConstructExpr{{.*}}, struct Bar)
// CHECK: ~Bar() (Temporary object destructor)
// CHECK: ~Bar() (Temporary object destructor)
// CHECK: ~TwoBars() (Implicit destructor)
TwoFoos
// CHECK: TwoFoos return_aggregate_init()
// CXX14: (CXXConstructExpr{{.*}}, struct Foo)
// CXX14: (CXXConstructExpr{{.*}}, struct Foo)
// CXX14: ~TwoFoos() (Temporary object destructor)
// CXX14: ~Foo() (Temporary object destructor)
// CXX14: ~Foo() (Temporary object destructor)
void
// CHECK: void lifetime_extended()
// CHECK: ~Foo() (Temporary object destructor)
// CHECK: one destroyed before, one destroyed after
// CHECK: ~Foo() (Implicit destructor)
void
// CHECK: void not_lifetime_extended()
// CXX14: (CXXConstructExpr{{.*}}, struct Foo)
// CHECK: ~Foo() (Temporary object destructor)
// CXX14: ~Foo() (Temporary object destructor)
// CHECK: one destroyed before, one destroyed after
// CHECK: ~Foo() (Implicit destructor)
void
// CHECK: void compound_literal()
// CHECK: (CXXConstructExpr, struct Bar)
// CHECK: (CXXConstructExpr, struct Bar)
// CHECK: ~Bar[2]() (Temporary object destructor)
Foo
// CHECK: Foo elided_return()
// CXX14: (CXXConstructExpr{{.*}}, struct Foo)
// CXX14: ~Foo() (Temporary object destructor)
auto
// CHECK: (lambda at {{.*}}) elided_return_lambda()
// CXX14: (CXXConstructExpr{{.*}}, class (lambda at {{.*}}))
// CXX14: ~(lambda at {{.*}})() (Temporary object destructor)
// CXX14: ~Foo() (Temporary object destructor)
void
// CHECK: void const_auto_obj()
// CHECK: .~Bar() (Implicit destructor)
void ;
void
// CHECK: void test_default_arg()
// CXX14: ~Foo() (Temporary object destructor)
// CHECK: ~Foo() (Temporary object destructor)
;
void
// CHECK: void default_ctor_with_default_arg()
// CHECK: CXXConstructExpr, {{.*}}, struct DefaultArgInCtor[3]
// CXX14: ~Foo() (Temporary object destructor)
// CHECK: ~Foo() (Temporary object destructor)
// CHECK: .~DefaultArgInCtor[3]() (Implicit destructor)
void
// CHECK: void new_default_ctor_with_default_arg(long count)
// CHECK: CXXConstructExpr, {{.*}}, struct DefaultArgInCtor[]
// CXX14: ~Foo() (Temporary object destructor)
// CHECK: ~Foo() (Temporary object destructor)
// Boilerplate needed to test co_return:
// namespace std
;
// namespace std
Bar
// CXX2A: Bar coreturn()
// CXX2A: ~Foo() (Temporary object destructor)
// CXX2A: ~Bar() (Temporary object destructor)