Author: dergachev Date: Fri Feb 23 19:10:15 2018 New Revision: 326019 URL: http://llvm.org/viewvc/llvm-project?rev=326019&view=rev Log: [CFG] Provide construction contexts for temporaries in conditional operators.
When a lifetime-extended temporary is on a branch of a conditional operator, materialization of such temporary occurs after the condition is resolved. This change allows us to understand, by including the MaterializeTemporaryExpr in the construction context, the target for temporary materialization in such cases. Differential Revision: https://reviews.llvm.org/D43483 Modified: cfe/trunk/lib/Analysis/CFG.cpp cfe/trunk/test/Analysis/cfg-rich-constructors.cpp cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp Modified: cfe/trunk/lib/Analysis/CFG.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=326019&r1=326018&r2=326019&view=diff ============================================================================== --- cfe/trunk/lib/Analysis/CFG.cpp (original) +++ cfe/trunk/lib/Analysis/CFG.cpp Fri Feb 23 19:10:15 2018 @@ -1187,6 +1187,9 @@ void CFGBuilder::findConstructionContext ConstructionContext::create(cfg->getBumpVectorContext(), BTE, ContextSoFar), BTE->getSubExpr()); + } else if (auto *CO = dyn_cast<ConditionalOperator>(Child)) { + findConstructionContexts(ContextSoFar, CO->getLHS()); + findConstructionContexts(ContextSoFar, CO->getRHS()); } } Modified: cfe/trunk/test/Analysis/cfg-rich-constructors.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/cfg-rich-constructors.cpp?rev=326019&r1=326018&r2=326019&view=diff ============================================================================== --- cfe/trunk/test/Analysis/cfg-rich-constructors.cpp (original) +++ cfe/trunk/test/Analysis/cfg-rich-constructors.cpp Fri Feb 23 19:10:15 2018 @@ -105,7 +105,6 @@ void simpleVariableInitializedByValue() 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 @@ void simpleVariableInitializedByValue() // 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 @@ void referenceVariableWithInitializer() 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 @@ void referenceVariableWithInitializer() // 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 @@ void referenceVariableWithInitializer() // 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 @@ void referenceVariableWithInitializer() // 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 referenceVariableWithTernaryOperato 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 Modified: cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp?rev=326019&r1=326018&r2=326019&view=diff ============================================================================== --- cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp (original) +++ cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp Fri Feb 23 19:10:15 2018 @@ -537,7 +537,7 @@ int testConsistencyNestedNormalReturn(bo // 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 @@ int testConsistencyNestedNormalReturn(bo // 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 @@ int testConsistencyNestedNormalReturn(bo // 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 @@ int testConsistencyNestedNormalReturn(bo // 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 @@ int testConsistencyNestedNormalReturn(bo // 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 @@ int testConsistencyNestedNormalReturn(bo // 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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits