Index: cfe/trunk/lib/Analysis/CFG.cpp =================================================================== --- cfe/trunk/lib/Analysis/CFG.cpp +++ cfe/trunk/lib/Analysis/CFG.cpp @@ -3169,7 +3169,13 @@ if (VarDecl *VD = F->getConditionVariable()) { if (Expr *Init = VD->getInit()) { autoCreateBlock(); - appendStmt(Block, F->getConditionVariableDeclStmt()); + const DeclStmt *DS = F->getConditionVariableDeclStmt(); + assert(DS->isSingleDecl()); + findConstructionContexts( + ConstructionContextLayer::create(cfg->getBumpVectorContext(), + const_cast(DS)), + Init); + appendStmt(Block, DS); EntryConditionBlock = addStmt(Init); assert(Block == EntryConditionBlock); maybeAddScopeBeginForVarDecl(EntryConditionBlock, VD, C); @@ -3494,7 +3500,13 @@ if (VarDecl *VD = W->getConditionVariable()) { if (Expr *Init = VD->getInit()) { autoCreateBlock(); - appendStmt(Block, W->getConditionVariableDeclStmt()); + const DeclStmt *DS = W->getConditionVariableDeclStmt(); + assert(DS->isSingleDecl()); + findConstructionContexts( + ConstructionContextLayer::create(cfg->getBumpVectorContext(), + const_cast(DS)), + Init); + appendStmt(Block, DS); EntryConditionBlock = addStmt(Init); assert(Block == EntryConditionBlock); maybeAddScopeBeginForVarDecl(EntryConditionBlock, VD, C); Index: cfe/trunk/test/Analysis/auto-obj-dtors-cfg-output.cpp =================================================================== --- cfe/trunk/test/Analysis/auto-obj-dtors-cfg-output.cpp +++ cfe/trunk/test/Analysis/auto-obj-dtors-cfg-output.cpp @@ -388,7 +388,8 @@ // CHECK: [B4] // CHECK-NEXT: 1: a // CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, NoOp, const class A) -// CHECK-NEXT: 3: [B4.2] (CXXConstructExpr, class A) +// WARNINGS-NEXT: 3: [B4.2] (CXXConstructExpr, class A) +// ANALYZER-NEXT: 3: [B4.2] (CXXConstructExpr, [B4.4], class A) // CHECK-NEXT: 4: A b = a; // CHECK-NEXT: 5: b // CHECK-NEXT: 6: [B4.5] (ImplicitCastExpr, NoOp, const class A) @@ -478,7 +479,8 @@ // CHECK: [B10] // CHECK-NEXT: 1: a // CHECK-NEXT: 2: [B10.1] (ImplicitCastExpr, NoOp, const class A) -// CHECK-NEXT: 3: [B10.2] (CXXConstructExpr, class A) +// WARNINGS-NEXT: 3: [B10.2] (CXXConstructExpr, class A) +// ANALYZER-NEXT: 3: [B10.2] (CXXConstructExpr, [B10.4], class A) // CHECK-NEXT: 4: A b = a; // CHECK-NEXT: 5: b // CHECK-NEXT: 6: [B10.5] (ImplicitCastExpr, NoOp, const class A) @@ -761,7 +763,8 @@ // CHECK: [B4] // CHECK-NEXT: 1: a // CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, NoOp, const class A) -// CHECK-NEXT: 3: [B4.2] (CXXConstructExpr, class A) +// WARNINGS-NEXT: 3: [B4.2] (CXXConstructExpr, class A) +// ANALYZER-NEXT: 3: [B4.2] (CXXConstructExpr, [B4.4], class A) // CHECK-NEXT: 4: A b = a; // CHECK-NEXT: 5: b // CHECK-NEXT: 6: [B4.5] (ImplicitCastExpr, NoOp, const class A) @@ -851,7 +854,8 @@ // CHECK: [B10] // CHECK-NEXT: 1: b // CHECK-NEXT: 2: [B10.1] (ImplicitCastExpr, NoOp, const class A) -// CHECK-NEXT: 3: [B10.2] (CXXConstructExpr, class A) +// WARNINGS-NEXT: 3: [B10.2] (CXXConstructExpr, class A) +// ANALYZER-NEXT: 3: [B10.2] (CXXConstructExpr, [B10.4], class A) // CHECK-NEXT: 4: A c = b; // CHECK-NEXT: 5: c // CHECK-NEXT: 6: [B10.5] (ImplicitCastExpr, NoOp, const class A) Index: cfe/trunk/test/Analysis/cfg-rich-constructors.cpp =================================================================== --- cfe/trunk/test/Analysis/cfg-rich-constructors.cpp +++ cfe/trunk/test/Analysis/cfg-rich-constructors.cpp @@ -450,6 +450,85 @@ if (C()); } +// CHECK: void temporaryInConditionVariable() +// CHECK: 1: C() (CXXConstructExpr, [B2.2], class C) +// CXX11-NEXT: 2: [B2.1] +// CXX11-NEXT: 3: [B2.2] (CXXConstructExpr, [B2.4], class C) +// CXX11-NEXT: 4: C c = C(); +// CXX11-NEXT: 5: c +// CXX11-NEXT: 6: [B2.5] (ImplicitCastExpr, NoOp, const class C) +// CXX11-NEXT: 7: [B2.6].operator bool +// CXX11-NEXT: 8: [B2.6] +// CXX11-NEXT: 9: [B2.8] (ImplicitCastExpr, UserDefinedConversion, _Bool) +// CXX11-NEXT: T: if [B2.9] +// CXX17-NEXT: 2: C c = C(); +// CXX17-NEXT: 3: c +// CXX17-NEXT: 4: [B2.3] (ImplicitCastExpr, NoOp, const class C) +// CXX17-NEXT: 5: [B2.4].operator bool +// CXX17-NEXT: 6: [B2.4] +// CXX17-NEXT: 7: [B2.6] (ImplicitCastExpr, UserDefinedConversion, _Bool) +// CXX17-NEXT: T: if [B2.7] +void temporaryInConditionVariable() { + if (C c = C()); +} + + +// CHECK: void temporaryInForLoopConditionVariable() +// CHECK: [B2] +// CXX11-NEXT: 1: C() (CXXConstructExpr, [B2.2], class C) +// CXX11-NEXT: 2: [B2.1] +// CXX11-NEXT: 3: [B2.2] (CXXConstructExpr, [B2.4], class C) +// CXX11-NEXT: 4: C c2 = C(); +// CXX11-NEXT: 5: c2 +// CXX11-NEXT: 6: [B2.5] (ImplicitCastExpr, NoOp, const class C) +// CXX11-NEXT: 7: [B2.6].operator bool +// CXX11-NEXT: 8: [B2.6] +// CXX11-NEXT: 9: [B2.8] (ImplicitCastExpr, UserDefinedConversion, _Bool) +// CXX11-NEXT: T: for (...; [B2.9]; ) +// CXX17-NEXT: 1: C() (CXXConstructExpr, [B2.2], class C) +// CXX17-NEXT: 2: C c2 = C(); +// CXX17-NEXT: 3: c2 +// CXX17-NEXT: 4: [B2.3] (ImplicitCastExpr, NoOp, const class C) +// CXX17-NEXT: 5: [B2.4].operator bool +// CXX17-NEXT: 6: [B2.4] +// CXX17-NEXT: 7: [B2.6] (ImplicitCastExpr, UserDefinedConversion, _Bool) +// CXX17-NEXT: T: for (...; [B2.7]; ) +// CHECK: [B3] +// CXX11-NEXT: 1: C() (CXXConstructExpr, [B3.2], class C) +// CXX11-NEXT: 2: [B3.1] +// CXX11-NEXT: 3: [B3.2] (CXXConstructExpr, [B3.4], class C) +// CXX11-NEXT: 4: C c1 = C(); +// CXX17-NEXT: 1: C() (CXXConstructExpr, [B3.2], class C) +// CXX17-NEXT: 2: C c1 = C(); +void temporaryInForLoopConditionVariable() { + for (C c1 = C(); C c2 = C(); ); +} + + +// FIXME: Find construction context for the loop condition variable. +// CHECK: void temporaryInWhileLoopConditionVariable() +// CXX11: 1: C() (CXXConstructExpr, [B2.2], class C) +// CXX11-NEXT: 2: [B2.1] +// CXX11-NEXT: 3: [B2.2] (CXXConstructExpr, [B2.4], class C) +// CXX11-NEXT: 4: C c = C(); +// CXX11-NEXT: 5: c +// CXX11-NEXT: 6: [B2.5] (ImplicitCastExpr, NoOp, const class C) +// CXX11-NEXT: 7: [B2.6].operator bool +// CXX11-NEXT: 8: [B2.6] +// CXX11-NEXT: 9: [B2.8] (ImplicitCastExpr, UserDefinedConversion, _Bool) +// CXX11-NEXT: T: while [B2.9] +// CXX17: 1: C() (CXXConstructExpr, [B2.2], class C) +// CXX17-NEXT: 2: C c = C(); +// CXX17-NEXT: 3: c +// CXX17-NEXT: 4: [B2.3] (ImplicitCastExpr, NoOp, const class C) +// CXX17-NEXT: 5: [B2.4].operator bool +// CXX17-NEXT: 6: [B2.4] +// CXX17-NEXT: 7: [B2.6] (ImplicitCastExpr, UserDefinedConversion, _Bool) +// CXX17-NEXT: T: while [B2.7] +void temporaryInWhileLoopConditionVariable() { + while (C c = C()); +} + } // end namespace temporary_object_expr_without_dtors namespace temporary_object_expr_with_dtors { Index: cfe/trunk/test/Analysis/scopes-cfg-output.cpp =================================================================== --- cfe/trunk/test/Analysis/scopes-cfg-output.cpp +++ cfe/trunk/test/Analysis/scopes-cfg-output.cpp @@ -296,7 +296,7 @@ // CHECK-NEXT: 1: CFGScopeBegin(b) // CHECK-NEXT: 2: a // CHECK-NEXT: 3: [B4.2] (ImplicitCastExpr, NoOp, const class A) -// CHECK-NEXT: 4: [B4.3] (CXXConstructExpr, class A) +// CHECK-NEXT: 4: [B4.3] (CXXConstructExpr, [B4.5], class A) // CHECK-NEXT: 5: A b = a; // CHECK-NEXT: 6: b // CHECK-NEXT: 7: [B4.6] (ImplicitCastExpr, NoOp, const class A) @@ -395,7 +395,7 @@ // CHECK-NEXT: 1: CFGScopeBegin(b) // CHECK-NEXT: 2: a // CHECK-NEXT: 3: [B10.2] (ImplicitCastExpr, NoOp, const class A) -// CHECK-NEXT: 4: [B10.3] (CXXConstructExpr, class A) +// CHECK-NEXT: 4: [B10.3] (CXXConstructExpr, [B10.5], class A) // CHECK-NEXT: 5: A b = a; // CHECK-NEXT: 6: b // CHECK-NEXT: 7: [B10.6] (ImplicitCastExpr, NoOp, const class A) @@ -540,7 +540,7 @@ // CHECK-NEXT: 1: CFGScopeBegin(b) // CHECK-NEXT: 2: a // CHECK-NEXT: 3: [B4.2] (ImplicitCastExpr, NoOp, const class A) -// CHECK-NEXT: 4: [B4.3] (CXXConstructExpr, class A) +// CHECK-NEXT: 4: [B4.3] (CXXConstructExpr, [B4.5], class A) // CHECK-NEXT: 5: A b = a; // CHECK-NEXT: 6: b // CHECK-NEXT: 7: [B4.6] (ImplicitCastExpr, NoOp, const class A) @@ -640,7 +640,7 @@ // CHECK-NEXT: 1: CFGScopeBegin(c) // CHECK-NEXT: 2: b // CHECK-NEXT: 3: [B10.2] (ImplicitCastExpr, NoOp, const class A) -// CHECK-NEXT: 4: [B10.3] (CXXConstructExpr, class A) +// CHECK-NEXT: 4: [B10.3] (CXXConstructExpr, [B10.5], class A) // CHECK-NEXT: 5: A c = b; // CHECK-NEXT: 6: c // CHECK-NEXT: 7: [B10.6] (ImplicitCastExpr, NoOp, const class A)