1061 lines · cpp
1// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -std=c++11 -w %s > %t 2>&12// RUN: FileCheck --input-file=%t -check-prefixes=CHECK,CXX11,CXX11-ELIDE %s3// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -std=c++17 -w %s > %t 2>&14// RUN: FileCheck --input-file=%t -check-prefixes=CHECK,CXX17 %s5// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -std=c++11 -w -analyzer-config elide-constructors=false %s > %t 2>&16// RUN: FileCheck --input-file=%t -check-prefixes=CHECK,CXX11,CXX11-NOELIDE %s7// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -std=c++17 -w -analyzer-config elide-constructors=false %s > %t 2>&18// RUN: FileCheck --input-file=%t -check-prefixes=CHECK,CXX17 %s9 10class C {11public:12 C();13 C(C *);14 C(int, int);15 16 static C get();17 operator bool() const;18};19 20typedef __typeof(sizeof(int)) size_t;21void *operator new(size_t size, void *placement);22 23namespace operator_new {24 25// CHECK: void operatorNewWithConstructor()26// CHECK: 1: CFGNewAllocator(C *)27// CHECK-NEXT: 2: (CXXConstructExpr, [B1.3], C)28// CHECK-NEXT: 3: new C([B1.2])29void operatorNewWithConstructor() {30 new C();31}32 33// CHECK: void operatorNewWithConstructorWithOperatorNewWithContstructor()34// CHECK: 1: CFGNewAllocator(C *)35// CHECK-NEXT: 2: CFGNewAllocator(C *)36// CHECK-NEXT: 3: (CXXConstructExpr, [B1.4], C)37// CHECK-NEXT: 4: new C([B1.3])38// CHECK-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6], C)39// CHECK-NEXT: 6: new C([B1.5])40void operatorNewWithConstructorWithOperatorNewWithContstructor() {41 new C(new C());42}43 44// CHECK: void operatorPlacementNewWithConstructorWithinPlacementArgument()45// CHECK: 1: CFGNewAllocator(C *)46// CHECK-NEXT: 2: (CXXConstructExpr, [B1.3], C)47// CHECK-NEXT: 3: new C([B1.2])48// CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, BitCast, void *)49// CHECK-NEXT: 5: CFGNewAllocator(C *)50// CHECK-NEXT: 6: (CXXConstructExpr, [B1.7], C)51// CHECK-NEXT: 7: new ([B1.4]) C([B1.6])52void operatorPlacementNewWithConstructorWithinPlacementArgument() {53 new (new C()) C();54}55 56} // namespace operator_new57 58namespace decl_stmt {59 60// CHECK: void simpleVariable()61// CHECK: 1: (CXXConstructExpr, [B1.2], C)62// CHECK-NEXT: 2: C c;63void simpleVariable() {64 C c;65}66 67// CHECK: void simpleVariableWithBraces()68// CHECK: 1: {} (CXXConstructExpr, [B1.2], C)69// CHECK-NEXT: 2: C c{};70void simpleVariableWithBraces() {71 C c{};72}73 74// CHECK: void simpleVariableWithConstructorArgument()75// CHECK: 1: 076// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NullToPointer, C *)77// CHECK-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.4], C)78// CHECK-NEXT: 4: C c(0);79void simpleVariableWithConstructorArgument() {80 C c(0);81}82 83// CHECK: void simpleVariableWithOperatorNewInConstructorArgument()84// CHECK: 1: CFGNewAllocator(C *)85// CHECK-NEXT: 2: (CXXConstructExpr, [B1.3], C)86// CHECK-NEXT: 3: new C([B1.2])87// CHECK-NEXT: 4: [B1.3] (CXXConstructExpr, [B1.5], C)88// CHECK-NEXT: 5: C c(new C());89void simpleVariableWithOperatorNewInConstructorArgument() {90 C c(new C());91}92 93// CHECK: void simpleVariableWithOperatorNewInBraces()94// CHECK: 1: CFGNewAllocator(C *)95// CHECK-NEXT: 2: (CXXConstructExpr, [B1.3], C)96// CHECK-NEXT: 3: new C([B1.2])97// CHECK-NEXT: 4: {[B1.3]} (CXXConstructExpr, [B1.5], C)98// CHECK-NEXT: 5: C c{new C()};99void simpleVariableWithOperatorNewInBraces() {100 C c{new C()};101}102 103// CHECK: void simpleVariableInitializedByValue()104// CHECK: 1: C::get105// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, C (*)(void))106// CXX11-ELIDE-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4], [B1.5])107// CXX11-NOELIDE-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4])108// CXX11-NEXT: 4: [B1.3]109// CXX11-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6], C)110// CXX11-NEXT: 6: C c = C::get();111// CXX17-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4])112// CXX17-NEXT: 4: C c = C::get();113void simpleVariableInitializedByValue() {114 C c = C::get();115}116 117// FIXME: Find construction contexts for both branches in C++17.118// Note that once it gets detected, the test for the get() branch would not119// fail, because FileCheck allows partial matches.120// CHECK: void simpleVariableWithTernaryOperator(bool coin)121// CHECK: [B1]122// CXX11-NEXT: 1: [B4.2] ? [B2.5] : [B3.6]123// CXX11-NEXT: 2: [B1.1]124// CXX11-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.4], C)125// CXX11-NEXT: 4: C c = coin ? C::get() : C(0);126// CXX17-NEXT: 1: [B4.2] ? [B2.3] : [B3.4]127// CXX17-NEXT: 2: C c = coin ? C::get() : C(0);128// CHECK: [B2]129// CHECK-NEXT: 1: C::get130// CHECK-NEXT: 2: [B2.1] (ImplicitCastExpr, FunctionToPointerDecay, C (*)(void))131// CXX11-ELIDE-NEXT: 3: [B2.2]() (CXXRecordTypedCall, [B2.4], [B2.5])132// CXX11-NOELIDE-NEXT: 3: [B2.2]() (CXXRecordTypedCall, [B2.4])133// CXX11-NEXT: 4: [B2.3]134// CXX11-ELIDE-NEXT: 5: [B2.4] (CXXConstructExpr, [B1.2], [B1.3], C)135// CXX11-NOELIDE-NEXT: 5: [B2.4] (CXXConstructExpr, [B1.2], C)136// CXX17-NEXT: 3: [B2.2]()137// CHECK: [B3]138// CHECK-NEXT: 1: 0139// CHECK-NEXT: 2: [B3.1] (ImplicitCastExpr, NullToPointer, C *)140// CXX11-ELIDE-NEXT: 3: [B3.2] (CXXConstructExpr, [B3.5], [B3.6], C)141// CXX11-NOELIDE-NEXT: 3: [B3.2] (CXXConstructExpr, [B3.5], C)142// CXX11-NEXT: 4: C([B3.3]) (CXXFunctionalCastExpr, ConstructorConversion, C)143// CXX11-NEXT: 5: [B3.4]144// CXX11-ELIDE-NEXT: 6: [B3.5] (CXXConstructExpr, [B1.2], [B1.3], C)145// CXX11-NOELIDE-NEXT: 6: [B3.5] (CXXConstructExpr, [B1.2], C)146// CXX17-NEXT: 3: [B3.2] (CXXConstructExpr, C)147// CXX17-NEXT: 4: C([B3.3]) (CXXFunctionalCastExpr, ConstructorConversion, C)148// CHECK: [B4]149// CHECK-NEXT: 1: coin150// CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, LValueToRValue, _Bool)151// CHECK-NEXT: T: [B4.2] ? ... : ...152void simpleVariableWithTernaryOperator(bool coin) {153 C c = coin ? C::get() : C(0);154}155 156// CHECK: void simpleVariableWithElidableCopy()157// CHECK: 1: 0158// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NullToPointer, C *)159// CXX11-ELIDE-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.5], [B1.6], C)160// CXX11-NOELIDE-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.5], C)161// CXX17-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.5], C)162// CHECK-NEXT: 4: C([B1.3]) (CXXFunctionalCastExpr, ConstructorConversion, C)163// CXX11-NEXT: 5: [B1.4]164// CXX11-NEXT: 6: [B1.5] (CXXConstructExpr, [B1.7], C)165// CXX11-NEXT: 7: C c = C(0);166// CXX17-NEXT: 5: C c = C(0);167void simpleVariableWithElidableCopy() {168 C c = C(0);169}170 171// CHECK: void referenceVariableWithConstructor()172// CHECK: 1: 0173// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NullToPointer, C *)174// CHECK-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.4], const C)175// CHECK-NEXT: 4: [B1.3]176// CHECK-NEXT: 5: const C &c(0);177void referenceVariableWithConstructor() {178 const C &c(0);179}180 181// CHECK: void referenceVariableWithInitializer()182// CHECK: 1: C() (CXXConstructExpr, [B1.3], C)183// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NoOp, const C)184// CHECK-NEXT: 3: [B1.2]185// CHECK-NEXT: 4: const C &c = C();186void referenceVariableWithInitializer() {187 const C &c = C();188}189 190// CHECK: void referenceVariableWithTernaryOperator(bool coin)191// CHECK: [B1]192// CXX11-NEXT: 1: [B4.2] ? [B2.5] : [B3.6]193// CXX17-NEXT: 1: [B4.2] ? [B2.3] : [B3.4]194// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NoOp, const C)195// CHECK-NEXT: 3: [B1.2]196// CHECK-NEXT: 4: const C &c = coin ? C::get() : C(0);197// CHECK: [B2]198// CHECK-NEXT: 1: C::get199// CHECK-NEXT: 2: [B2.1] (ImplicitCastExpr, FunctionToPointerDecay, C (*)(void))200// CXX11-ELIDE-NEXT: 3: [B2.2]() (CXXRecordTypedCall, [B2.4], [B2.5])201// CXX11-NOELIDE-NEXT: 3: [B2.2]() (CXXRecordTypedCall, [B2.4])202// CXX11-NEXT: 4: [B2.3]203// CXX11-NEXT: 5: [B2.4] (CXXConstructExpr, [B1.3], C)204// CXX17-NEXT: 3: [B2.2]() (CXXRecordTypedCall, [B1.3])205// CHECK: [B3]206// CHECK-NEXT: 1: 0207// CHECK-NEXT: 2: [B3.1] (ImplicitCastExpr, NullToPointer, C *)208// CXX11-ELIDE-NEXT: 3: [B3.2] (CXXConstructExpr, [B3.5], [B3.6], C)209// CXX11-NOELIDE-NEXT: 3: [B3.2] (CXXConstructExpr, [B3.5], C)210// CXX11-NEXT: 4: C([B3.3]) (CXXFunctionalCastExpr, ConstructorConversion, C)211// CXX11-NEXT: 5: [B3.4]212// CXX11-NEXT: 6: [B3.5] (CXXConstructExpr, [B1.3], C)213// CXX17-NEXT: 3: [B3.2] (CXXConstructExpr, [B1.3], C)214// CXX17-NEXT: 4: C([B3.3]) (CXXFunctionalCastExpr, ConstructorConversion, C)215// CHECK: [B4]216// CHECK-NEXT: 1: coin217// CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, LValueToRValue, _Bool)218// CHECK-NEXT: T: [B4.2] ? ... : ...219void referenceVariableWithTernaryOperator(bool coin) {220 const C &c = coin ? C::get() : C(0);221}222 223} // end namespace decl_stmt224 225namespace ctor_initializers {226 227class D: public C {228 C c1;229 230public:231 232// CHECK: D()233// CHECK: 1: (CXXConstructExpr, C() (Base initializer), C)234// CHECK-NEXT: 2: C([B1.1]) (Base initializer)235// CHECK-NEXT: 3: CFGNewAllocator(C *)236// CHECK-NEXT: 4: (CXXConstructExpr, [B1.5], C)237// CHECK-NEXT: 5: new C([B1.4])238// CHECK-NEXT: 6: [B1.5] (CXXConstructExpr, c1([B1.5]) (Member initializer), C)239// CHECK-NEXT: 7: c1([B1.6]) (Member initializer)240 D(): C(), c1(new C()) {}241 242// CHECK: D(int)243// CHECK: 1: (CXXConstructExpr, D() (Delegating initializer), class ctor_initializers::D)244// CHECK-NEXT: 2: D([B1.1]) (Delegating initializer)245 D(int): D() {}246 247// FIXME: Why is CXXRecordTypedCall not present in C++17? Note that once it gets248// detected the test would not fail, because FileCheck allows partial matches.249// CHECK: D(double)250// CHECK: 1: C::get251// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, C (*)(void))252// CHECK-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4])253// CHECK-NEXT: 4: [B1.3]254// CHECK-NEXT: 5: [B1.4] (CXXConstructExpr, C([B1.4]) (Base initializer), C)255// CHECK-NEXT: 6: C([B1.5]) (Base initializer)256// CHECK-NEXT: 7: CFGNewAllocator(C *)257// CHECK-NEXT: 8: C::get258// CHECK-NEXT: 9: [B1.8] (ImplicitCastExpr, FunctionToPointerDecay, C (*)(void))259// CXX11-ELIDE-NEXT: 10: [B1.9]() (CXXRecordTypedCall, [B1.11], [B1.12])260// CXX11-NOELIDE-NEXT: 10: [B1.9]() (CXXRecordTypedCall, [B1.11])261// CXX11-NEXT: 11: [B1.10]262// CXX11-NEXT: 12: [B1.11] (CXXConstructExpr, [B1.13], C)263// CXX11-NEXT: 13: new C([B1.12])264// CXX11-NEXT: 14: [B1.13] (CXXConstructExpr, c1([B1.13]) (Member initializer), C)265// CXX11-NEXT: 15: c1([B1.14]) (Member initializer)266// CXX17-NEXT: 10: [B1.9]()267// CXX17-NEXT: 11: new C([B1.10])268// CXX17-NEXT: 12: [B1.11] (CXXConstructExpr, c1([B1.11]) (Member initializer), C)269// CXX17-NEXT: 13: c1([B1.12]) (Member initializer)270 D(double): C(C::get()), c1(new C(C::get())) {}271};272 273// Let's see if initializers work well for fields with destructors.274class E {275public:276 static E get();277 ~E();278};279 280class F {281 E e;282 283public:284// FIXME: There should be no temporary destructor in C++17.285// CHECK: F()286// CHECK: 1: E::get287// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, E (*)(288// CXX11-ELIDE-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4], [B1.6], [B1.7])289// CXX11-NOELIDE-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4], [B1.6])290// CXX11-NEXT: 4: [B1.3] (BindTemporary)291// CXX11-NEXT: 5: [B1.4] (ImplicitCastExpr, NoOp, const E)292// CXX11-NEXT: 6: [B1.5]293// CXX11-NEXT: 7: [B1.6] (CXXConstructExpr, e([B1.6]) (Member initializer), E)294// CXX11-NEXT: 8: e([B1.7]) (Member initializer)295// CXX11-NEXT: 9: ~E() (Temporary object destructor)296// CXX17-NEXT: 3: [B1.2]() (CXXRecordTypedCall, e([B1.4]) (Member initializer), [B1.4])297// CXX17-NEXT: 4: [B1.3] (BindTemporary)298// CXX17-NEXT: 5: e([B1.4]) (Member initializer)299// CXX17-NEXT: 6: ~E() (Temporary object destructor)300 F(): e(E::get()) {}301};302} // end namespace ctor_initializers303 304namespace return_stmt_without_dtor {305 306// CHECK: C returnVariable()307// CHECK: 1: (CXXConstructExpr, [B1.2], C)308// CHECK-NEXT: 2: C c;309// CHECK-NEXT: 3: c310// CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, NoOp, C)311// CHECK-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6], C)312// CHECK-NEXT: 6: return [B1.5];313C returnVariable() {314 C c;315 return c;316}317 318// CHECK: C returnEmptyBraces()319// CHECK: 1: {} (CXXConstructExpr, [B1.2], C)320// CHECK-NEXT: 2: return [B1.1];321C returnEmptyBraces() {322 return {};323}324 325// CHECK: C returnBracesWithOperatorNew()326// CHECK: 1: CFGNewAllocator(C *)327// CHECK-NEXT: 2: (CXXConstructExpr, [B1.3], C)328// CHECK-NEXT: 3: new C([B1.2])329// CHECK-NEXT: 4: {[B1.3]} (CXXConstructExpr, [B1.5], C)330// CHECK-NEXT: 5: return [B1.4];331C returnBracesWithOperatorNew() {332 return {new C()};333}334 335// CHECK: C returnBracesWithMultipleItems()336// CHECK: 1: 123337// CHECK-NEXT: 2: 456338// CHECK-NEXT: 3: {[B1.1], [B1.2]} (CXXConstructExpr, [B1.4], C)339// CHECK-NEXT: 4: return [B1.3];340C returnBracesWithMultipleItems() {341 return {123, 456};342}343 344// CHECK: C returnTemporary()345// CXX11-ELIDE: 1: C() (CXXConstructExpr, [B1.2], [B1.3], C)346// CXX11-NOELIDE: 1: C() (CXXConstructExpr, [B1.2], C)347// CXX11-NEXT: 2: [B1.1]348// CXX11-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.4], C)349// CXX11-NEXT: 4: return [B1.3];350// CXX17: 1: C() (CXXConstructExpr, [B1.2], C)351// CXX17-NEXT: 2: return [B1.1];352C returnTemporary() {353 return C();354}355 356// CHECK: C returnTemporaryWithArgument()357// CHECK: 1: nullptr358// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NullToPointer, C *)359// CXX11-ELIDE-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.5], [B1.6], C)360// CXX11-NOELIDE-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.5], C)361// CXX17-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.5], C)362// CHECK-NEXT: 4: C([B1.3]) (CXXFunctionalCastExpr, ConstructorConversion, C)363// CXX11-NEXT: 5: [B1.4]364// CXX11-NEXT: 6: [B1.5] (CXXConstructExpr, [B1.7], C)365// CXX11-NEXT: 7: return [B1.6];366// CXX17-NEXT: 5: return [B1.4];367 368C returnTemporaryWithArgument() {369 return C(nullptr);370}371 372// CHECK: C returnTemporaryConstructedByFunction()373// CHECK: 1: C::get374// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, C (*)(void))375// CXX11-ELIDE-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4], [B1.5])376// CXX11-NOELIDE-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4])377// CXX11-NEXT: 4: [B1.3]378// CXX11-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6], C)379// CXX11-NEXT: 6: return [B1.5];380// CXX17-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4])381// CXX17-NEXT: 4: return [B1.3];382C returnTemporaryConstructedByFunction() {383 return C::get();384}385 386// CHECK: C returnChainOfCopies()387// CHECK: 1: C::get388// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, C (*)(void))389// CXX11-ELIDE-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4], [B1.5])390// CXX11-NOELIDE-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4])391// CXX11-NEXT: 4: [B1.3]392// CXX11-ELIDE-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.7], [B1.8], C)393// CXX11-NOELIDE-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.7], C)394// CXX11-NEXT: 6: C([B1.5]) (CXXFunctionalCastExpr, ConstructorConversion, C)395// CXX11-NEXT: 7: [B1.6]396// CXX11-NEXT: 8: [B1.7] (CXXConstructExpr, [B1.9], C)397// CXX11-NEXT: 9: return [B1.8];398// CXX17-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.5])399// CXX17-NEXT: 4: C([B1.3]) (CXXFunctionalCastExpr, NoOp, C)400// CXX17-NEXT: 5: return [B1.4];401C returnChainOfCopies() {402 return C(C::get());403}404 405} // end namespace return_stmt_without_dtor406 407namespace return_stmt_with_dtor {408 409class D {410public:411 D();412 ~D();413};414 415// CHECK: D returnTemporary()416// CXX11-ELIDE: 1: D() (CXXConstructExpr, [B1.2], [B1.4], [B1.5], D)417// CXX11-NOELIDE: 1: D() (CXXConstructExpr, [B1.2], [B1.4], D)418// CXX11-NEXT: 2: [B1.1] (BindTemporary)419// CXX11-NEXT: 3: [B1.2] (ImplicitCastExpr, NoOp, const D)420// CXX11-NEXT: 4: [B1.3]421// CXX11-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.7], D)422// CXX11-NEXT: 6: ~D() (Temporary object destructor)423// CXX11-NEXT: 7: return [B1.5];424// CXX17: 1: D() (CXXConstructExpr, [B1.3], [B1.2], D)425// CXX17-NEXT: 2: [B1.1] (BindTemporary)426// CXX17-NEXT: 3: return [B1.2];427D returnTemporary() {428 return D();429}430 431// CHECK: void returnByValueIntoVariable()432// CHECK: 1: returnTemporary433// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, D (*)(void))434// CXX11-ELIDE-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4], [B1.6], [B1.7])435// CXX11-NOELIDE-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4], [B1.6])436// CXX11-NEXT: 4: [B1.3] (BindTemporary)437// CXX11-NEXT: 5: [B1.4] (ImplicitCastExpr, NoOp, const D)438// CXX11-NEXT: 6: [B1.5]439// CXX11-NEXT: 7: [B1.6] (CXXConstructExpr, [B1.8], D)440// CXX11-NEXT: 8: D d = returnTemporary();441// CXX11-NEXT: 9: ~D() (Temporary object destructor)442// CXX11-NEXT: 10: [B1.8].~D() (Implicit destructor)443// CXX17-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.5], [B1.4])444// CXX17-NEXT: 4: [B1.3] (BindTemporary)445// CXX17-NEXT: 5: D d = returnTemporary();446void returnByValueIntoVariable() {447 D d = returnTemporary();448}449 450} // end namespace return_stmt_with_dtor451 452namespace temporary_object_expr_without_dtors {453 454// TODO: Should provide construction context for the constructor,455// even if there is no specific trigger statement here.456// CHECK: void simpleTemporary()457// CHECK: 1: C() (CXXConstructExpr, C)458void simpleTemporary() {459 C();460}461 462// CHECK: void temporaryInCondition()463// CHECK: 1: C() (CXXConstructExpr, [B2.2], C)464// CHECK-NEXT: 2: [B2.1]465// CHECK-NEXT: 3: [B2.2] (ImplicitCastExpr, NoOp, const class C)466// CHECK-NEXT: 4: [B2.3].operator bool467// CHECK-NEXT: 5: [B2.3]468// CHECK-NEXT: 6: [B2.5] (ImplicitCastExpr, UserDefinedConversion, _Bool)469// CHECK-NEXT: T: if [B2.6]470void temporaryInCondition() {471 if (C());472}473 474// CHECK: void temporaryInConditionVariable()475// CXX11-ELIDE: 1: C() (CXXConstructExpr, [B2.2], [B2.3], C)476// CXX11-NOELIDE: 1: C() (CXXConstructExpr, [B2.2], C)477// CXX11-NEXT: 2: [B2.1]478// CXX11-NEXT: 3: [B2.2] (CXXConstructExpr, [B2.4], C)479// CXX11-NEXT: 4: C c = C();480// CXX11-NEXT: 5: c481// CXX11-NEXT: 6: [B2.5] (ImplicitCastExpr, NoOp, const class C)482// CXX11-NEXT: 7: [B2.6].operator bool483// CXX11-NEXT: 8: [B2.6]484// CXX11-NEXT: 9: [B2.8] (ImplicitCastExpr, UserDefinedConversion, _Bool)485// CXX11-NEXT: T: if [B2.9]486// CXX17: 1: C() (CXXConstructExpr, [B2.2], C)487// CXX17-NEXT: 2: C c = C();488// CXX17-NEXT: 3: c489// CXX17-NEXT: 4: [B2.3] (ImplicitCastExpr, NoOp, const class C)490// CXX17-NEXT: 5: [B2.4].operator bool491// CXX17-NEXT: 6: [B2.4]492// CXX17-NEXT: 7: [B2.6] (ImplicitCastExpr, UserDefinedConversion, _Bool)493// CXX17-NEXT: T: if [B2.7]494void temporaryInConditionVariable() {495 if (C c = C());496}497 498 499// CHECK: void temporaryInForLoopConditionVariable()500// CHECK: [B2]501// CXX11-ELIDE-NEXT: 1: C() (CXXConstructExpr, [B2.2], [B2.3], C)502// CXX11-NOELIDE-NEXT: 1: C() (CXXConstructExpr, [B2.2], C)503// CXX11-NEXT: 2: [B2.1]504// CXX11-NEXT: 3: [B2.2] (CXXConstructExpr, [B2.4], C)505// CXX11-NEXT: 4: C c2 = C();506// CXX11-NEXT: 5: c2507// CXX11-NEXT: 6: [B2.5] (ImplicitCastExpr, NoOp, const class C)508// CXX11-NEXT: 7: [B2.6].operator bool509// CXX11-NEXT: 8: [B2.6]510// CXX11-NEXT: 9: [B2.8] (ImplicitCastExpr, UserDefinedConversion, _Bool)511// CXX11-NEXT: T: for (...; [B2.9]; )512// CXX17-NEXT: 1: C() (CXXConstructExpr, [B2.2], C)513// CXX17-NEXT: 2: C c2 = C();514// CXX17-NEXT: 3: c2515// CXX17-NEXT: 4: [B2.3] (ImplicitCastExpr, NoOp, const class C)516// CXX17-NEXT: 5: [B2.4].operator bool517// CXX17-NEXT: 6: [B2.4]518// CXX17-NEXT: 7: [B2.6] (ImplicitCastExpr, UserDefinedConversion, _Bool)519// CXX17-NEXT: T: for (...; [B2.7]; )520// CHECK: [B3]521// CXX11-ELIDE-NEXT: 1: C() (CXXConstructExpr, [B3.2], [B3.3], C)522// CXX11-NOELIDE-NEXT: 1: C() (CXXConstructExpr, [B3.2], C)523// CXX11-NEXT: 2: [B3.1]524// CXX11-NEXT: 3: [B3.2] (CXXConstructExpr, [B3.4], C)525// CXX11-NEXT: 4: C c1 = C();526// CXX17-NEXT: 1: C() (CXXConstructExpr, [B3.2], C)527// CXX17-NEXT: 2: C c1 = C();528void temporaryInForLoopConditionVariable() {529 for (C c1 = C(); C c2 = C(); );530}531 532 533// CHECK: void temporaryInWhileLoopConditionVariable()534// CXX11-ELIDE: 1: C() (CXXConstructExpr, [B2.2], [B2.3], C)535// CXX11-NOELIDE: 1: C() (CXXConstructExpr, [B2.2], C)536// CXX11-NEXT: 2: [B2.1]537// CXX11-NEXT: 3: [B2.2] (CXXConstructExpr, [B2.4], C)538// CXX11-NEXT: 4: C c = C();539// CXX11-NEXT: 5: c540// CXX11-NEXT: 6: [B2.5] (ImplicitCastExpr, NoOp, const class C)541// CXX11-NEXT: 7: [B2.6].operator bool542// CXX11-NEXT: 8: [B2.6]543// CXX11-NEXT: 9: [B2.8] (ImplicitCastExpr, UserDefinedConversion, _Bool)544// CXX11-NEXT: T: while [B2.9]545// CXX17: 1: C() (CXXConstructExpr, [B2.2], C)546// CXX17-NEXT: 2: C c = C();547// CXX17-NEXT: 3: c548// CXX17-NEXT: 4: [B2.3] (ImplicitCastExpr, NoOp, const class C)549// CXX17-NEXT: 5: [B2.4].operator bool550// CXX17-NEXT: 6: [B2.4]551// CXX17-NEXT: 7: [B2.6] (ImplicitCastExpr, UserDefinedConversion, _Bool)552// CXX17-NEXT: T: while [B2.7]553void temporaryInWhileLoopConditionVariable() {554 while (C c = C());555}556 557} // end namespace temporary_object_expr_without_dtors558 559namespace temporary_object_expr_with_dtors {560 561class D {562public:563 D();564 D(int);565 ~D();566 567 static D get();568 569 operator bool() const;570};571 572// CHECK: void simpleTemporary()573// CHECK: 1: D() (CXXConstructExpr, [B1.2], D)574// CHECK-NEXT: 2: [B1.1] (BindTemporary)575// CHECK-NEXT: 3: ~D() (Temporary object destructor)576void simpleTemporary() {577 D();578}579 580// CHECK: void temporaryInCondition()581// CHECK: 1: D() (CXXConstructExpr, [B2.2], [B2.3], D)582// CHECK-NEXT: 2: [B2.1] (BindTemporary)583// CHECK-NEXT: 3: [B2.2]584// CHECK-NEXT: 4: [B2.3] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D)585// CHECK-NEXT: 5: [B2.4].operator bool586// CHECK-NEXT: 6: [B2.4]587// CHECK-NEXT: 7: [B2.6] (ImplicitCastExpr, UserDefinedConversion, _Bool)588// CHECK-NEXT: 8: ~D() (Temporary object destructor)589// CHECK-NEXT: T: if [B2.7]590void temporaryInCondition() {591 if (D());592}593 594// CHECK: void referenceVariableWithConstructor()595// CHECK: 1: 0596// CHECK-NEXT: 2: [B1.1] (CXXConstructExpr, [B1.4], const D)597// CHECK-NEXT: 3: [B1.2] (BindTemporary)598// CHECK-NEXT: 4: [B1.3]599// CHECK-NEXT: 5: const D &d(0);600// CHECK-NEXT: 6: [B1.5].~D() (Implicit destructor)601void referenceVariableWithConstructor() {602 const D &d(0);603}604 605// CHECK: void referenceVariableWithInitializer()606// CHECK: 1: D() (CXXConstructExpr, [B1.4], D)607// CHECK-NEXT: 2: [B1.1] (BindTemporary)608// CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, NoOp, const D)609// CHECK-NEXT: 4: [B1.3]610// CHECK-NEXT: 5: const D &d = D();611// CHECK-NEXT: 6: [B1.5].~D() (Implicit destructor)612void referenceVariableWithInitializer() {613 const D &d = D();614}615 616// CHECK: void referenceVariableWithTernaryOperator(bool coin)617// CXX11: [B1]618// CXX11-NEXT: 1: [B4.4].~D() (Implicit destructor)619// CXX11: [B2]620// CXX11-NEXT: 1: ~D() (Temporary object destructor)621// CXX11: [B3]622// CXX11-NEXT: 1: ~D() (Temporary object destructor)623// CXX11: [B4]624// CXX11-NEXT: 1: [B7.2] ? [B5.8] : [B6.8]625// CXX11-NEXT: 2: [B4.1] (ImplicitCastExpr, NoOp, const D)626// CXX11-NEXT: 3: [B4.2]627// CXX11-NEXT: 4: const D &d = coin ? D::get() : D(0);628// CXX11-NEXT: T: (Temp Dtor) [B6.3]629// CXX11: [B5]630// CXX11-NEXT: 1: D::get631// CXX11-NEXT: 2: [B5.1] (ImplicitCastExpr, FunctionToPointerDecay, D (*)(void))632// CXX11-ELIDE-NEXT: 3: [B5.2]() (CXXRecordTypedCall, [B5.4], [B5.6], [B5.7])633// CXX11-NOELIDE-NEXT: 3: [B5.2]() (CXXRecordTypedCall, [B5.4], [B5.6])634// CXX11-NEXT: 4: [B5.3] (BindTemporary)635// CXX11-NEXT: 5: [B5.4] (ImplicitCastExpr, NoOp, const D)636// CXX11-NEXT: 6: [B5.5]637// CXX11-NEXT: 7: [B5.6] (CXXConstructExpr, [B4.3], D)638// CXX11-NEXT: 8: [B5.7] (BindTemporary)639// CXX11: [B6]640// CXX11-NEXT: 1: 0641// CXX11-ELIDE-NEXT: 2: [B6.1] (CXXConstructExpr, [B6.3], [B6.6], [B6.7], D)642// CXX11-NOELIDE-NEXT: 2: [B6.1] (CXXConstructExpr, [B6.3], [B6.6], D)643// CXX11-NEXT: 3: [B6.2] (BindTemporary)644// CXX11-NEXT: 4: D([B6.3]) (CXXFunctionalCastExpr, ConstructorConversion, D)645// CXX11-NEXT: 5: [B6.4] (ImplicitCastExpr, NoOp, const D)646// CXX11-NEXT: 6: [B6.5]647// CXX11-NEXT: 7: [B6.6] (CXXConstructExpr, [B4.3], D)648// CXX11-NEXT: 8: [B6.7] (BindTemporary)649// CXX11: [B7]650// CXX11-NEXT: 1: coin651// CXX11-NEXT: 2: [B7.1] (ImplicitCastExpr, LValueToRValue, _Bool)652// CXX11-NEXT: T: [B7.2] ? ... : ...653// CXX17: [B1]654// CXX17-NEXT: 1: [B4.2] ? [B2.4] : [B3.4]655// CXX17-NEXT: 2: [B1.1] (ImplicitCastExpr, NoOp, const D)656// CXX17-NEXT: 3: [B1.2]657// CXX17-NEXT: 4: const D &d = coin ? D::get() : D(0);658// CXX17-NEXT: 5: [B1.4].~D() (Implicit destructor)659// CXX17: [B2]660// CXX17-NEXT: 1: D::get661// CXX17-NEXT: 2: [B2.1] (ImplicitCastExpr, FunctionToPointerDecay, D (*)(void))662// CXX17-NEXT: 3: [B2.2]() (CXXRecordTypedCall, [B1.3])663// CXX17-NEXT: 4: [B2.3] (BindTemporary)664// CXX17: [B3]665// CXX17-NEXT: 1: 0666// CXX17-NEXT: 2: [B3.1] (CXXConstructExpr, [B1.3], D)667// CXX17-NEXT: 3: [B3.2] (BindTemporary)668// CXX17-NEXT: 4: D([B3.3]) (CXXFunctionalCastExpr, ConstructorConversion, D)669// CXX17: [B4]670// CXX17-NEXT: 1: coin671// CXX17-NEXT: 2: [B4.1] (ImplicitCastExpr, LValueToRValue, _Bool)672// CXX17-NEXT: T: [B4.2] ? ... : ...673void referenceVariableWithTernaryOperator(bool coin) {674 const D &d = coin ? D::get() : D(0);675}676 677// CHECK: void referenceWithFunctionalCast()678// CHECK: 1: 1679// CHECK-NEXT: 2: [B1.1] (CXXConstructExpr, [B1.5], D)680// CHECK-NEXT: 3: [B1.2] (BindTemporary)681// CHECK-NEXT: 4: D([B1.3]) (CXXFunctionalCastExpr, ConstructorCon682// CHECK-NEXT: 5: [B1.4]683// CHECK-NEXT: 6: D &&d = D(1);684// CHECK-NEXT: 7: [B1.6].~D() (Implicit destructor)685void referenceWithFunctionalCast() {686 D &&d = D(1);687}688 689// Test the condition constructor, we don't care about branch constructors here.690// CHECK: void constructorInTernaryCondition()691// CXX11: 1: 1692// CXX11-NEXT: 2: [B7.1] (CXXConstructExpr, [B7.3], [B7.5], D)693// CXX11-NEXT: 3: [B7.2] (BindTemporary)694// CXX11-NEXT: 4: D([B7.3]) (CXXFunctionalCastExpr, ConstructorConversion, D)695// CXX11-NEXT: 5: [B7.4]696// CXX11-NEXT: 6: [B7.5] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D)697// CXX11-NEXT: 7: [B7.6].operator bool698// CXX11-NEXT: 8: [B7.6]699// CXX11-NEXT: 9: [B7.8] (ImplicitCastExpr, UserDefinedConversion, _Bool)700// CXX11-NEXT: T: [B7.9] ? ... : ...701// CXX17: 1: 1702// CXX17-NEXT: 2: [B4.1] (CXXConstructExpr, [B4.3], [B4.5], D)703// CXX17-NEXT: 3: [B4.2] (BindTemporary)704// CXX17-NEXT: 4: D([B4.3]) (CXXFunctionalCastExpr, ConstructorConversion, D)705// CXX17-NEXT: 5: [B4.4]706// CXX17-NEXT: 6: [B4.5] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D)707// CXX17-NEXT: 7: [B4.6].operator bool708// CXX17-NEXT: 8: [B4.6]709// CXX17-NEXT: 9: [B4.8] (ImplicitCastExpr, UserDefinedConversion, _Bool)710// CXX17-NEXT: T: [B4.9] ? ... : ...711void constructorInTernaryCondition() {712 const D &d = D(1) ? D(2) : D(3);713}714 715} // end namespace temporary_object_expr_with_dtors716 717namespace implicit_constructor_conversion {718 719class A {};720A get();721 722class B {723public:724 B(const A &);725 ~B() {}726};727 728// CHECK: void implicitConstructionConversionFromTemporary()729// CHECK: 1: A() (CXXConstructExpr, [B1.3], A)730// CXX11-NEXT: 2: [B1.1] (ImplicitCastExpr, NoOp, const A)731// CXX11-NEXT: 3: [B1.2]732// CXX11-ELIDE-NEXT: 4: [B1.3] (CXXConstructExpr, [B1.6], [B1.8], [B1.9], B)733// CXX11-NOELIDE-NEXT: 4: [B1.3] (CXXConstructExpr, [B1.6], [B1.8], B)734// CXX11-NEXT: 5: [B1.4] (ImplicitCastExpr, ConstructorConversion, B)735// CXX11-NEXT: 6: [B1.5] (BindTemporary)736// CXX11-NEXT: 7: [B1.6] (ImplicitCastExpr, NoOp, const B)737// CXX11-NEXT: 8: [B1.7]738// CXX11-NEXT: 9: [B1.8] (CXXConstructExpr, [B1.10], B)739// CXX11-NEXT: 10: B b = A();740// CXX11-NEXT: 11: ~B() (Temporary object destructor)741// CXX11-NEXT: 12: [B1.10].~B() (Implicit destructor)742// CXX17-NEXT: 2: [B1.1] (ImplicitCastExpr, NoOp, const A)743// CXX17-NEXT: 3: [B1.2]744// CXX17-NEXT: 4: [B1.3] (CXXConstructExpr, [B1.6], B)745// CXX17-NEXT: 5: [B1.4] (ImplicitCastExpr, ConstructorConversion, B)746// CXX17-NEXT: 6: B b = A();747// CXX17-NEXT: 7: [B1.6].~B() (Implicit destructor)748void implicitConstructionConversionFromTemporary() {749 B b = A();750}751 752// CHECK: void implicitConstructionConversionFromFunctionValue()753// CHECK: 1: get754// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, A (*)(void))755// CHECK-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.5])756// CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, NoOp, const A)757// CHECK-NEXT: 5: [B1.4]758// CXX11-ELIDE-NEXT: 6: [B1.5] (CXXConstructExpr, [B1.8], [B1.10], [B1.11], B)759// CXX11-NOELIDE-NEXT: 6: [B1.5] (CXXConstructExpr, [B1.8], [B1.10], B)760// CXX11-NEXT: 7: [B1.6] (ImplicitCastExpr, ConstructorConversion, B)761// CXX11-NEXT: 8: [B1.7] (BindTemporary)762// CXX11-NEXT: 9: [B1.8] (ImplicitCastExpr, NoOp, const B)763// CXX11-NEXT: 10: [B1.9]764// CXX11-NEXT: 11: [B1.10] (CXXConstructExpr, [B1.12], B)765// CXX11-NEXT: 12: B b = get();766// CXX11-NEXT: 13: ~B() (Temporary object destructor)767// CXX11-NEXT: 14: [B1.12].~B() (Implicit destructor)768// CXX17-NEXT: 6: [B1.5] (CXXConstructExpr, [B1.8], B)769// CXX17-NEXT: 7: [B1.6] (ImplicitCastExpr, ConstructorConversion, B)770// CXX17-NEXT: 8: B b = get();771// CXX17-NEXT: 9: [B1.8].~B() (Implicit destructor)772void implicitConstructionConversionFromFunctionValue() {773 B b = get();774}775 776// CHECK: void implicitConstructionConversionFromTemporaryWithLifetimeExtension()777// CHECK: 1: A() (CXXConstructExpr, [B1.3], A)778// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, NoOp, const A)779// CHECK-NEXT: 3: [B1.2]780// CHECK-NEXT: 4: [B1.3] (CXXConstructExpr, [B1.7], B)781// CHECK-NEXT: 5: [B1.4] (ImplicitCastExpr, ConstructorConversion, B)782// CHECK-NEXT: 6: [B1.5] (ImplicitCastExpr, NoOp, const B)783// CHECK-NEXT: 7: [B1.6]784// CHECK-NEXT: 8: const B &b = A();785// CHECK-NEXT: 9: [B1.8].~B() (Implicit destructor)786void implicitConstructionConversionFromTemporaryWithLifetimeExtension() {787 const B &b = A();788}789 790// CHECK: void implicitConstructionConversionFromFunctionValueWithLifetimeExtension()791// CHECK: 1: get792// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, A (*)(void))793// CHECK-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.5])794// CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, NoOp, const A)795// CHECK-NEXT: 5: [B1.4]796// CHECK-NEXT: 6: [B1.5] (CXXConstructExpr, [B1.9], B)797// CHECK-NEXT: 7: [B1.6] (ImplicitCastExpr, ConstructorConversion, B)798// CHECK-NEXT: 8: [B1.7] (ImplicitCastExpr, NoOp, const B)799// CHECK-NEXT: 9: [B1.8]800// CHECK-NEXT: 10: const B &b = get();801// CHECK-NEXT: 11: [B1.10].~B() (Implicit destructor)802void implicitConstructionConversionFromFunctionValueWithLifetimeExtension() {803 const B &b = get(); // no-crash804}805 806} // end namespace implicit_constructor_conversion807 808namespace argument_constructors {809class D {810public:811 D();812 ~D();813};814 815class E {816public:817 E(D d);818 E(D d1, D d2);819};820 821void useC(C c);822void useCByReference(const C &c);823void useD(D d);824void useDByReference(const D &d);825void useCAndD(C c, D d);826 827// CHECK: void passArgument()828// CHECK: 1: useC829// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(C))830// CXX11-ELIDE-NEXT: 3: C() (CXXConstructExpr, [B1.4], [B1.5], C)831// CXX11-NOELIDE-NEXT: 3: C() (CXXConstructExpr, [B1.4], C)832// CXX11-NEXT: 4: [B1.3]833// CXX11-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6]+0, C)834// CXX11-NEXT: 6: [B1.2]([B1.5])835// CXX17-NEXT: 3: C() (CXXConstructExpr, [B1.4]+0, C)836// CXX17-NEXT: 4: [B1.2]([B1.3])837void passArgument() {838 useC(C());839}840 841// CHECK: void passTwoArguments()842// CHECK: [B1]843// CHECK-NEXT: 1: useCAndD844// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(C, D))845// CXX11-ELIDE-NEXT: 3: C() (CXXConstructExpr, [B1.4], [B1.5], C)846// CXX11-NOELIDE-NEXT: 3: C() (CXXConstructExpr, [B1.4], C)847// CXX11-NEXT: 4: [B1.3]848// CXX11-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.12]+0, C)849// CXX11-ELIDE-NEXT: 6: D() (CXXConstructExpr, [B1.7], [B1.9], [B1.10], D)850// CXX11-NOELIDE-NEXT: 6: D() (CXXConstructExpr, [B1.7], [B1.9], D)851// CXX11-NEXT: 7: [B1.6] (BindTemporary)852// CXX11-NEXT: 8: [B1.7] (ImplicitCastExpr, NoOp, const D)853// CXX11-NEXT: 9: [B1.8]854// CXX11-NEXT: 10: [B1.9] (CXXConstructExpr, [B1.11], [B1.12]+1, D)855// CXX11-NEXT: 11: [B1.10] (BindTemporary)856// CXX11-NEXT: 12: [B1.2]([B1.5], [B1.11])857// CXX11-NEXT: 13: ~D() (Temporary object destructor)858// CXX11-NEXT: 14: ~D() (Temporary object destructor)859// CXX17-NEXT: 3: C() (CXXConstructExpr, [B1.6]+0, C)860// CXX17-NEXT: 4: D() (CXXConstructExpr, [B1.5], [B1.6]+1, D)861// CXX17-NEXT: 5: [B1.4] (BindTemporary)862// CXX17-NEXT: 6: [B1.2]([B1.3], [B1.5])863// CXX17-NEXT: 7: ~D() (Temporary object destructor)864void passTwoArguments() {865 useCAndD(C(), D());866}867 868// CHECK: void passArgumentByReference()869// CHECK: 1: useCByReference870// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(const C &))871// CHECK-NEXT: 3: C() (CXXConstructExpr, [B1.5], C)872// CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, NoOp, const C)873// CHECK-NEXT: 5: [B1.4]874// CHECK-NEXT: 6: [B1.2]([B1.5])875void passArgumentByReference() {876 useCByReference(C());877}878 879// CHECK: void passArgumentWithDestructor()880// CHECK: 1: useD881// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(D))882// CXX11-ELIDE-NEXT: 3: D() (CXXConstructExpr, [B1.4], [B1.6], [B1.7], D)883// CXX11-NOELIDE-NEXT: 3: D() (CXXConstructExpr, [B1.4], [B1.6], D)884// CXX11-NEXT: 4: [B1.3] (BindTemporary)885// CXX11-NEXT: 5: [B1.4] (ImplicitCastExpr, NoOp, const D)886// CXX11-NEXT: 6: [B1.5]887// CXX11-NEXT: 7: [B1.6] (CXXConstructExpr, [B1.8], [B1.9]+0, D)888// CXX11-NEXT: 8: [B1.7] (BindTemporary)889// CXX11-NEXT: 9: [B1.2]([B1.8])890// CXX11-NEXT: 10: ~D() (Temporary object destructor)891// CXX11-NEXT: 11: ~D() (Temporary object destructor)892// CXX17-NEXT: 3: D() (CXXConstructExpr, [B1.4], [B1.5]+0, D)893// CXX17-NEXT: 4: [B1.3] (BindTemporary)894// CXX17-NEXT: 5: [B1.2]([B1.4])895// CXX17-NEXT: 6: ~D() (Temporary object destructor)896void passArgumentWithDestructor() {897 useD(D());898}899 900// CHECK: void passArgumentWithDestructorByReference()901// CHECK: 1: useDByReference902// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(const D &))903// CHECK-NEXT: 3: D() (CXXConstructExpr, [B1.4], [B1.6], D)904// CHECK-NEXT: 4: [B1.3] (BindTemporary)905// CHECK-NEXT: 5: [B1.4] (ImplicitCastExpr, NoOp, const D)906// CHECK-NEXT: 6: [B1.5]907// CHECK-NEXT: 7: [B1.2]([B1.6])908// CHECK-NEXT: 8: ~D() (Temporary object destructor)909void passArgumentWithDestructorByReference() {910 useDByReference(D());911}912 913// CHECK: void passArgumentIntoAnotherConstructor()914// CXX11-ELIDE: 1: D() (CXXConstructExpr, [B1.2], [B1.4], [B1.5], D)915// CXX11-NOELIDE: 1: D() (CXXConstructExpr, [B1.2], [B1.4], D)916// CXX11-NEXT: 2: [B1.1] (BindTemporary)917// CXX11-NEXT: 3: [B1.2] (ImplicitCastExpr, NoOp, const D)918// CXX11-NEXT: 4: [B1.3]919// CXX11-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6], [B1.7]+0, D)920// CXX11-NEXT: 6: [B1.5] (BindTemporary)921// CXX11-ELIDE-NEXT: 7: [B1.6] (CXXConstructExpr, [B1.9], [B1.10], E)922// CXX11-NOELIDE-NEXT: 7: [B1.6] (CXXConstructExpr, [B1.9], E)923// CXX11-NEXT: 8: E([B1.7]) (CXXFunctionalCastExpr, ConstructorConversion, E)924// CXX11-NEXT: 9: [B1.8]925// CXX11-NEXT: 10: [B1.9] (CXXConstructExpr, [B1.11], E)926// CXX11-NEXT: 11: E e = E(D());927// CXX11-NEXT: 12: ~D() (Temporary object destructor)928// CXX11-NEXT: 13: ~D() (Temporary object destructor)929// CXX17: 1: D() (CXXConstructExpr, [B1.2], [B1.3]+0, D)930// CXX17-NEXT: 2: [B1.1] (BindTemporary)931// CXX17-NEXT: 3: [B1.2] (CXXConstructExpr, [B1.5], E)932// CXX17-NEXT: 4: E([B1.3]) (CXXFunctionalCastExpr, ConstructorConversion, E)933// CXX17-NEXT: 5: E e = E(D());934// CXX17-NEXT: 6: ~D() (Temporary object destructor)935void passArgumentIntoAnotherConstructor() {936 E e = E(D());937}938 939 940// CHECK: void passTwoArgumentsIntoAnotherConstructor()941// CXX11-ELIDE: 1: D() (CXXConstructExpr, [B1.2], [B1.4], [B1.5], D)942// CXX11-NOELIDE: 1: D() (CXXConstructExpr, [B1.2], [B1.4], D)943// CXX11-NEXT: 2: [B1.1] (BindTemporary)944// CXX11-NEXT: 3: [B1.2] (ImplicitCastExpr, NoOp, const D)945// CXX11-NEXT: 4: [B1.3]946// CXX11-NEXT: 5: [B1.4] (CXXConstructExpr, [B1.6], [B1.13]+0, D)947// CXX11-NEXT: 6: [B1.5] (BindTemporary)948// CXX11-ELIDE-NEXT: 7: D() (CXXConstructExpr, [B1.8], [B1.10], [B1.11], D)949// CXX11-NOELIDE-NEXT: 7: D() (CXXConstructExpr, [B1.8], [B1.10], D)950// CXX11-NEXT: 8: [B1.7] (BindTemporary)951// CXX11-NEXT: 9: [B1.8] (ImplicitCastExpr, NoOp, const D)952// CXX11-NEXT: 10: [B1.9]953// CXX11-NEXT: 11: [B1.10] (CXXConstructExpr, [B1.12], [B1.13]+1, D)954// CXX11-NEXT: 12: [B1.11] (BindTemporary)955// CXX11-NEXT: 13: E([B1.6], [B1.12]) (CXXConstructExpr, E)956// CXX11-NEXT: 14: ~D() (Temporary object destructor)957// CXX11-NEXT: 15: ~D() (Temporary object destructor)958// CXX11-NEXT: 16: ~D() (Temporary object destructor)959// CXX11-NEXT: 17: ~D() (Temporary object destructor)960// CXX17: 1: D() (CXXConstructExpr, [B1.2], [B1.5]+0, D)961// CXX17-NEXT: 2: [B1.1] (BindTemporary)962// CXX17-NEXT: 3: D() (CXXConstructExpr, [B1.4], [B1.5]+1, D)963// CXX17-NEXT: 4: [B1.3] (BindTemporary)964// CXX17-NEXT: 5: E([B1.2], [B1.4]) (CXXConstructExpr, E)965// CXX17-NEXT: 6: ~D() (Temporary object destructor)966// CXX17-NEXT: 7: ~D() (Temporary object destructor)967void passTwoArgumentsIntoAnotherConstructor() {968 E(D(), D());969}970} // end namespace argument_constructors971 972namespace copy_elision_with_extra_arguments {973class C {974public:975 C();976 C(const C &c, int x = 0);977};978 979// CHECK: void testCopyElisionWhenCopyConstructorHasExtraArguments()980// CHECK: [B1]981// CXX11-ELIDE-NEXT: 1: C() (CXXConstructExpr, [B1.3], [B1.5], C)982// CXX11-NOELIDE-NEXT: 1: C() (CXXConstructExpr, [B1.3], C)983// CXX11-NEXT: 2: [B1.1] (ImplicitCastExpr, NoOp, const C)984// CXX11-NEXT: 3: [B1.2]985// CXX11-NEXT: 4:986// CXX11-NEXT: 5: [B1.3] (CXXConstructExpr, [B1.6], C)987// CXX11-NEXT: 6: C c = C();988// CXX17-NEXT: 1: C() (CXXConstructExpr, [B1.2], C)989// CXX17-NEXT: 2: C c = C();990void testCopyElisionWhenCopyConstructorHasExtraArguments() {991 C c = C();992}993} // namespace copy_elision_with_extra_arguments994 995 996namespace operators {997class C {998public:999 C(int);1000 C &operator+(C Other);1001};1002 1003// FIXME: Find construction context for the this-argument of the operator.1004// CHECK: void testOperators()1005// CHECK: [B1]1006// CHECK-NEXT: 1: operator+1007// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, C &(*)(C))1008// CHECK-NEXT: 3: 11009// CHECK-NEXT: 4: [B1.3] (CXXConstructExpr, [B1.6], C)1010// CHECK-NEXT: 5: C([B1.4]) (CXXFunctionalCastExpr, ConstructorConversion, C)1011// CHECK-NEXT: 6: [B1.5]1012// CHECK-NEXT: 7: 21013// CXX11-ELIDE-NEXT: 8: [B1.7] (CXXConstructExpr, [B1.10], [B1.11], C)1014// CXX11-NOELIDE-NEXT: 8: [B1.7] (CXXConstructExpr, [B1.10], C)1015// CXX11-NEXT: 9: C([B1.8]) (CXXFunctionalCastExpr, ConstructorConversion, C)1016// CXX11-NEXT: 10: [B1.9]1017// CXX11-NEXT: 11: [B1.10] (CXXConstructExpr, [B1.12]+1, C)1018// CXX11-NEXT: 12: [B1.6] + [B1.11] (OperatorCall)1019// CXX17-NEXT: 8: [B1.7] (CXXConstructExpr, [B1.10]+1, C)1020// CXX17-NEXT: 9: C([B1.8]) (CXXFunctionalCastExpr, ConstructorConversion, C)1021// CXX17-NEXT: 10: [B1.6] + [B1.9] (OperatorCall)1022void testOperators() {1023 C(1) + C(2);1024}1025} // namespace operators1026 1027namespace variadic_function_arguments {1028class C {1029 public:1030 C(int);1031};1032 1033int variadic(...);1034 1035// This code is quite exotic, so let's not test the CFG for it,1036// but only make sure we don't crash.1037void testCrashOnVariadicArgument() {1038 C c(variadic(0 ? c : 0)); // no-crash1039}1040} // namespace variadic_function_arguments1041 1042// CHECK: void testTransparentInitListExprs()1043// CHECK: [B1]1044// CHECK-NEXT: 1: getC1045// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, C (*)(void))1046// CXX11-ELIDE-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4], [B1.5])1047// CXX11-NOELIDE-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.4])1048// CXX11-NEXT: 4: [B1.3]1049// CXX11-NEXT: 5: {[B1.4]} (CXXConstructExpr, [B1.6], C)1050// CXX11-NEXT: 6: C c{getC()};1051// CXX17-NEXT: 3: [B1.2]() (CXXRecordTypedCall, [B1.5])1052// CXX17-NEXT: 4: {[B1.3]}1053// CXX17-NEXT: 5: C c{getC()};1054namespace transparent_init_list_exprs {1055class C {};1056C getC();1057void testTransparentInitListExprs() {1058 C c{getC()};1059}1060} // namespace transparent_init_list_exprs1061