Index: cfe/trunk/lib/Analysis/CFG.cpp =================================================================== --- cfe/trunk/lib/Analysis/CFG.cpp +++ cfe/trunk/lib/Analysis/CFG.cpp @@ -1187,6 +1187,9 @@ ConstructionContext::create(cfg->getBumpVectorContext(), BTE, ContextSoFar), BTE->getSubExpr()); + } else if (auto *CO = dyn_cast(Child)) { + findConstructionContexts(ContextSoFar, CO->getLHS()); + findConstructionContexts(ContextSoFar, CO->getRHS()); } } 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 @@ -105,7 +105,6 @@ C c = C::get(); } -// TODO: Should find construction target for the elidable constructors as well. // CHECK: void simpleVariableWithTernaryOperator(bool coin) // CHECK: [B1] // CHECK-NEXT: 1: [B4.2] ? [B2.5] : [B3.6] @@ -117,14 +116,14 @@ // CHECK-NEXT: 2: [B2.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void)) // CHECK-NEXT: 3: [B2.2]() // CHECK-NEXT: 4: [B2.3] -// CHECK-NEXT: 5: [B2.4] (CXXConstructExpr, class C) +// CHECK-NEXT: 5: [B2.4] (CXXConstructExpr, [B1.2], class C) // CHECK: [B3] // CHECK-NEXT: 1: 0 // CHECK-NEXT: 2: [B3.1] (ImplicitCastExpr, NullToPointer, class C *) // CHECK-NEXT: 3: [B3.2] (CXXConstructExpr, [B3.5], class C) // CHECK-NEXT: 4: C([B3.3]) (CXXFunctionalCastExpr, ConstructorConversion, class C) // CHECK-NEXT: 5: [B3.4] -// CHECK-NEXT: 6: [B3.5] (CXXConstructExpr, class C) +// CHECK-NEXT: 6: [B3.5] (CXXConstructExpr, [B1.2], class C) // CHECK: [B4] // CHECK-NEXT: 1: coin // CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, LValueToRValue, _Bool) @@ -164,7 +163,6 @@ const C &c = C(); } -// TODO: Should find construction targets for the elidable constructors as well. // CHECK: void referenceVariableWithTernaryOperator(bool coin) // CHECK: [B1] // CHECK-NEXT: 1: [B4.2] ? [B2.5] : [B3.6] @@ -176,14 +174,14 @@ // CHECK-NEXT: 2: [B2.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void)) // CHECK-NEXT: 3: [B2.2]() // CHECK-NEXT: 4: [B2.3] -// CHECK-NEXT: 5: [B2.4] (CXXConstructExpr, class C) +// CHECK-NEXT: 5: [B2.4] (CXXConstructExpr, [B1.3], class C) // CHECK: [B3] // CHECK-NEXT: 1: 0 // CHECK-NEXT: 2: [B3.1] (ImplicitCastExpr, NullToPointer, class C *) // CHECK-NEXT: 3: [B3.2] (CXXConstructExpr, [B3.5], class C) // CHECK-NEXT: 4: C([B3.3]) (CXXFunctionalCastExpr, ConstructorConversion, class C) // CHECK-NEXT: 5: [B3.4] -// CHECK-NEXT: 6: [B3.5] (CXXConstructExpr, class C) +// CHECK-NEXT: 6: [B3.5] (CXXConstructExpr, [B1.3], class C) // CHECK: [B4] // CHECK-NEXT: 1: coin // CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, LValueToRValue, _Bool) @@ -441,7 +439,7 @@ // CHECK-NEXT: 4: [B5.3] (BindTemporary) // CHECK-NEXT: 5: [B5.4] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D) // CHECK-NEXT: 6: [B5.5] -// CHECK-NEXT: 7: [B5.6] (CXXConstructExpr, [B5.8], class temporary_object_expr_with_dtors::D) +// CHECK-NEXT: 7: [B5.6] (CXXConstructExpr, [B5.8], [B4.3], class temporary_object_expr_with_dtors::D) // CHECK-NEXT: 8: [B5.7] (BindTemporary) // CHECK: [B6] // CHECK-NEXT: 1: 0 @@ -450,7 +448,7 @@ // CHECK-NEXT: 4: temporary_object_expr_with_dtors::D([B6.3]) (CXXFunctionalCastExpr, ConstructorConversion, class temporary_object_expr_with_dtors::D) // CHECK-NEXT: 5: [B6.4] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D) // CHECK-NEXT: 6: [B6.5] -// CHECK-NEXT: 7: [B6.6] (CXXConstructExpr, [B6.8], class temporary_object_expr_with_dtors::D) +// CHECK-NEXT: 7: [B6.6] (CXXConstructExpr, [B6.8], [B4.3], class temporary_object_expr_with_dtors::D) // CHECK-NEXT: 8: [B6.7] (BindTemporary) // CHECK: [B7] // CHECK-NEXT: 1: coin @@ -471,4 +469,19 @@ void referenceWithFunctionalCast() { D &&d = D(1); } + +// Test the condition constructor, we don't care about branch constructors here. +// CHECK: void constructorInTernaryCondition() +// CHECK: 1: 1 +// CHECK-NEXT: 2: [B7.1] (CXXConstructExpr, [B7.3], class temporary_object_expr_with_dtors::D) +// CHECK-NEXT: 3: [B7.2] (BindTemporary) +// CHECK-NEXT: 4: temporary_object_expr_with_dtors::D([B7.3]) (CXXFunctionalCastExpr, ConstructorConv +// CHECK-NEXT: 5: [B7.4] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D) +// CHECK-NEXT: 6: [B7.5].operator bool +// CHECK-NEXT: 7: [B7.5] +// CHECK-NEXT: 8: [B7.7] (ImplicitCastExpr, UserDefinedConversion, _Bool) +// CHECK-NEXT: T: [B7.8] ? ... : ... +void constructorInTernaryCondition() { + const D &d = D(1) ? D(2) : D(3); +} } // end namespace temporary_object_expr_with_dtors Index: cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp =================================================================== --- cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp +++ cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp @@ -537,7 +537,7 @@ // CHECK: 3: [B8.2] (ImplicitCastExpr, NoOp, const class A) // CHECK: 4: [B8.3] // WARNINGS: 5: [B8.4] (CXXConstructExpr, class A) -// ANALYZER: 5: [B8.4] (CXXConstructExpr, [B8.6], class A) +// ANALYZER: 5: [B8.4] (CXXConstructExpr, [B8.6], [B7.3], class A) // CHECK: 6: [B8.5] (BindTemporary) // CHECK: Preds (1): B10 // CHECK: Succs (1): B7 @@ -558,7 +558,7 @@ // CHECK: 12: [B9.11] (ImplicitCastExpr, NoOp, const class A) // CHECK: 13: [B9.12] // WARNINGS: 14: [B9.13] (CXXConstructExpr, class A) -// ANALYZER: 14: [B9.13] (CXXConstructExpr, [B9.15], class A) +// ANALYZER: 14: [B9.13] (CXXConstructExpr, [B9.15], [B7.3], class A) // CHECK: 15: [B9.14] (BindTemporary) // CHECK: Preds (1): B10 // CHECK: Succs (1): B7 @@ -776,7 +776,7 @@ // CHECK: 3: [B5.2] (ImplicitCastExpr, NoOp, const class A) // CHECK: 4: [B5.3] // WARNINGS: 5: [B5.4] (CXXConstructExpr, class A) -// ANALYZER: 5: [B5.4] (CXXConstructExpr, [B5.6], class A) +// ANALYZER: 5: [B5.4] (CXXConstructExpr, [B5.6], [B4.3], class A) // CHECK: 6: [B5.5] (BindTemporary) // CHECK: Preds (1): B7 // CHECK: Succs (1): B4 @@ -797,7 +797,7 @@ // CHECK: 12: [B6.11] (ImplicitCastExpr, NoOp, const class A) // CHECK: 13: [B6.12] // WARNINGS: 14: [B6.13] (CXXConstructExpr, class A) -// ANALYZER: 14: [B6.13] (CXXConstructExpr, [B6.15], class A) +// ANALYZER: 14: [B6.13] (CXXConstructExpr, [B6.15], [B4.3], class A) // CHECK: 15: [B6.14] (BindTemporary) // CHECK: Preds (1): B7 // CHECK: Succs (1): B4 @@ -839,7 +839,7 @@ // CHECK: 3: [B11.2] (ImplicitCastExpr, NoOp, const class A) // CHECK: 4: [B11.3] // WARNINGS: 5: [B11.4] (CXXConstructExpr, class A) -// ANALYZER: 5: [B11.4] (CXXConstructExpr, [B11.6], class A) +// ANALYZER: 5: [B11.4] (CXXConstructExpr, [B11.6], [B10.3], class A) // CHECK: 6: [B11.5] (BindTemporary) // CHECK: Preds (1): B13 // CHECK: Succs (1): B10 @@ -860,7 +860,7 @@ // CHECK: 12: [B12.11] (ImplicitCastExpr, NoOp, const class A) // CHECK: 13: [B12.12] // WARNINGS: 14: [B12.13] (CXXConstructExpr, class A) -// ANALYZER: 14: [B12.13] (CXXConstructExpr, [B12.15], class A) +// ANALYZER: 14: [B12.13] (CXXConstructExpr, [B12.15], [B10.3], class A) // CHECK: 15: [B12.14] (BindTemporary) // CHECK: Preds (1): B13 // CHECK: Succs (1): B10