Author: dergachev Date: Wed Jun 27 17:18:52 2018 New Revision: 335798 URL: http://llvm.org/viewvc/llvm-project?rev=335798&view=rev Log: [CFG] [analyzer] Simplify lifetime-extended temporary construction contexts.
When a temporary object is materialized and through that obtain lifetime that is longer than the duration of the full-expression, it does not require a temporary object destructor; it will be destroyed in a different manner. Therefore it's not necessary to include CXXBindTemporaryExpr into the construction context for such temporary in the CFG only to make clients throw it away. Differential Revision: https://reviews.llvm.org/D47667 Modified: cfe/trunk/lib/Analysis/ConstructionContext.cpp cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp cfe/trunk/test/Analysis/auto-obj-dtors-cfg-output.cpp cfe/trunk/test/Analysis/cfg-rich-constructors.cpp cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp Modified: cfe/trunk/lib/Analysis/ConstructionContext.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ConstructionContext.cpp?rev=335798&r1=335797&r2=335798&view=diff ============================================================================== --- cfe/trunk/lib/Analysis/ConstructionContext.cpp (original) +++ cfe/trunk/lib/Analysis/ConstructionContext.cpp Wed Jun 27 17:18:52 2018 @@ -76,6 +76,13 @@ const ConstructionContext *ConstructionC // both destruction and materialization info attached to it in the AST. if ((MTE = dyn_cast<MaterializeTemporaryExpr>( ParentLayer->getTriggerStmt()))) { + if (MTE->getStorageDuration() != SD_FullExpression) { + // If the temporary is lifetime-extended, don't save the BTE, + // because we don't need a temporary destructor, but an automatic + // destructor. + BTE = nullptr; + } + // Handle pre-C++17 copy and move elision. const CXXConstructExpr *ElidedCE = nullptr; const ConstructionContext *ElidedCC = nullptr; Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp?rev=335798&r1=335797&r2=335798&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp Wed Jun 27 17:18:52 2018 @@ -217,6 +217,7 @@ std::pair<ProgramStateRef, SVal> ExprEng const auto *TCC = cast<TemporaryObjectConstructionContext>(CC); const CXXBindTemporaryExpr *BTE = TCC->getCXXBindTemporaryExpr(); const MaterializeTemporaryExpr *MTE = TCC->getMaterializedTemporaryExpr(); + SVal V = UnknownVal(); if (MTE) { if (const ValueDecl *VD = MTE->getExtendingDecl()) { @@ -230,14 +231,6 @@ std::pair<ProgramStateRef, SVal> ExprEng CallOpts.IsTemporaryLifetimeExtendedViaAggregate = true; } } - } - - SVal V = UnknownVal(); - if (MTE && MTE->getStorageDuration() != SD_FullExpression) { - // If the temporary is lifetime-extended, don't save the BTE, - // because we don't need a temporary destructor, but an automatic - // destructor. - BTE = nullptr; if (MTE->getStorageDuration() == SD_Static || MTE->getStorageDuration() == SD_Thread) Modified: cfe/trunk/test/Analysis/auto-obj-dtors-cfg-output.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/auto-obj-dtors-cfg-output.cpp?rev=335798&r1=335797&r2=335798&view=diff ============================================================================== --- cfe/trunk/test/Analysis/auto-obj-dtors-cfg-output.cpp (original) +++ cfe/trunk/test/Analysis/auto-obj-dtors-cfg-output.cpp Wed Jun 27 17:18:52 2018 @@ -56,7 +56,7 @@ extern const bool UV; // CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, NoOp, const class A) // CHECK-NEXT: 5: const A &b = a; // WARNINGS-NEXT: 6: A() (CXXConstructExpr, class A) -// ANALYZER-NEXT: 6: A() (CXXConstructExpr, [B1.7], [B1.9], class A) +// ANALYZER-NEXT: 6: A() (CXXConstructExpr, [B1.9], class A) // CHECK-NEXT: 7: [B1.6] (BindTemporary) // CHECK-NEXT: 8: [B1.7] (ImplicitCastExpr, NoOp, const class A) // CHECK-NEXT: 9: [B1.8] @@ -78,7 +78,7 @@ void test_const_ref() { // CHECK: [B1] // WARNINGS-NEXT: 1: A() (CXXConstructExpr, class A) // CXX98-ANALYZER-NEXT: 1: A() (CXXConstructExpr, [B1.2], class A) -// CXX11-ANALYZER-NEXT: 1: A() (CXXConstructExpr, [B1.2], [B1.3], class A) +// CXX11-ANALYZER-NEXT: 1: A() (CXXConstructExpr, [B1.3], class A) // CHECK-NEXT: 2: [B1.1] (BindTemporary) // CXX98-NEXT: 3: [B1.2].x // CXX98-NEXT: 4: [B1.3] @@ -102,7 +102,7 @@ void test_const_ref_to_field() { // CHECK: [B1] // WARNINGS-NEXT: 1: A() (CXXConstructExpr, class A) // CXX98-ANALYZER-NEXT: 1: A() (CXXConstructExpr, [B1.2], class A) -// CXX11-ANALYZER-NEXT: 1: A() (CXXConstructExpr, [B1.2], [B1.3], class A) +// CXX11-ANALYZER-NEXT: 1: A() (CXXConstructExpr, [B1.3], class A) // CHECK-NEXT: 2: [B1.1] (BindTemporary) // CXX98-NEXT: 3: A::x // CXX98-NEXT: 4: &[B1.3] @@ -130,20 +130,20 @@ void test_pointer_to_member() { // CHECK-NEXT: Succs (1): B1 // CHECK: [B1] // WARNINGS-NEXT: 1: A() (CXXConstructExpr, class A) -// ANALYZER-NEXT: 1: A() (CXXConstructExpr, [B1.2], [B1.4], class A) +// ANALYZER-NEXT: 1: A() (CXXConstructExpr, [B1.4], class A) // CHECK-NEXT: 2: [B1.1] (BindTemporary) // CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, NoOp, const class A) // CHECK-NEXT: 4: [B1.3] // CHECK-NEXT: 5: {[B1.4]} // CHECK-NEXT: 6: B b = {A()}; // WARNINGS-NEXT: 7: A() (CXXConstructExpr, class A) -// ANALYZER-NEXT: 7: A() (CXXConstructExpr, [B1.8], [B1.10], class A) +// ANALYZER-NEXT: 7: A() (CXXConstructExpr, [B1.10], class A) // CHECK-NEXT: 8: [B1.7] (BindTemporary) // CHECK-NEXT: 9: [B1.8] (ImplicitCastExpr, NoOp, const class A) // CHECK-NEXT: 10: [B1.9] // CHECK-NEXT: 11: {[B1.10]} // WARNINGS-NEXT: 12: A() (CXXConstructExpr, class A) -// ANALYZER-NEXT: 12: A() (CXXConstructExpr, [B1.13], [B1.15], class A) +// ANALYZER-NEXT: 12: A() (CXXConstructExpr, [B1.15], class A) // CHECK-NEXT: 13: [B1.12] (BindTemporary) // CHECK-NEXT: 14: [B1.13] (ImplicitCastExpr, NoOp, const class A) // CHECK-NEXT: 15: [B1.14] 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=335798&r1=335797&r2=335798&view=diff ============================================================================== --- cfe/trunk/test/Analysis/cfg-rich-constructors.cpp (original) +++ cfe/trunk/test/Analysis/cfg-rich-constructors.cpp Wed Jun 27 17:18:52 2018 @@ -597,7 +597,7 @@ void temporaryInCondition() { // CHECK: void referenceVariableWithConstructor() // CHECK: 1: 0 -// CHECK-NEXT: 2: [B1.1] (CXXConstructExpr, [B1.3], [B1.4], const class temporary_object_expr_with_dtors::D) +// CHECK-NEXT: 2: [B1.1] (CXXConstructExpr, [B1.4], const class temporary_object_expr_with_dtors::D) // CHECK-NEXT: 3: [B1.2] (BindTemporary) // CHECK-NEXT: 4: [B1.3] // CHECK-NEXT: 5: const temporary_object_expr_with_dtors::D &d(0); @@ -607,7 +607,7 @@ void referenceVariableWithConstructor() } // CHECK: void referenceVariableWithInitializer() -// CHECK: 1: temporary_object_expr_with_dtors::D() (CXXConstructExpr, [B1.2], [B1.4], class temporary_object_expr_with_dtors::D) +// CHECK: 1: temporary_object_expr_with_dtors::D() (CXXConstructExpr, [B1.4], class temporary_object_expr_with_dtors::D) // CHECK-NEXT: 2: [B1.1] (BindTemporary) // CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D) // CHECK-NEXT: 4: [B1.3] @@ -638,7 +638,7 @@ void referenceVariableWithInitializer() // CXX11-NEXT: 4: [B5.3] (BindTemporary) // CXX11-NEXT: 5: [B5.4] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D) // CXX11-NEXT: 6: [B5.5] -// CXX11-NEXT: 7: [B5.6] (CXXConstructExpr, [B5.8], [B4.3], class temporary_object_expr_with_dtors::D) +// CXX11-NEXT: 7: [B5.6] (CXXConstructExpr, [B4.3], class temporary_object_expr_with_dtors::D) // CXX11-NEXT: 8: [B5.7] (BindTemporary) // CXX11: [B6] // CXX11-NEXT: 1: 0 @@ -648,7 +648,7 @@ void referenceVariableWithInitializer() // CXX11-NEXT: 4: temporary_object_expr_with_dtors::D([B6.3]) (CXXFunctionalCastExpr, ConstructorConversion, class temporary_object_expr_with_dtors::D) // CXX11-NEXT: 5: [B6.4] (ImplicitCastExpr, NoOp, const class temporary_object_expr_with_dtors::D) // CXX11-NEXT: 6: [B6.5] -// CXX11-NEXT: 7: [B6.6] (CXXConstructExpr, [B6.8], [B4.3], class temporary_object_expr_with_dtors::D) +// CXX11-NEXT: 7: [B6.6] (CXXConstructExpr, [B4.3], class temporary_object_expr_with_dtors::D) // CXX11-NEXT: 8: [B6.7] (BindTemporary) // CXX11: [B7] // CXX11-NEXT: 1: coin @@ -663,11 +663,11 @@ void referenceVariableWithInitializer() // CXX17: [B2] // CXX17-NEXT: 1: D::get // CXX17-NEXT: 2: [B2.1] (ImplicitCastExpr, FunctionToPointerDecay, class temporary_object_expr_with_dtors::D (*)(void)) -// CXX17-NEXT: 3: [B2.2]() (CXXRecordTypedCall, [B2.4], [B1.3]) +// CXX17-NEXT: 3: [B2.2]() (CXXRecordTypedCall, [B1.3]) // CXX17-NEXT: 4: [B2.3] (BindTemporary) // CXX17: [B3] // CXX17-NEXT: 1: 0 -// CXX17-NEXT: 2: [B3.1] (CXXConstructExpr, [B3.3], [B1.3], class temporary_object_expr_with_dtors::D) +// CXX17-NEXT: 2: [B3.1] (CXXConstructExpr, [B1.3], class temporary_object_expr_with_dtors::D) // CXX17-NEXT: 3: [B3.2] (BindTemporary) // CXX17-NEXT: 4: temporary_object_expr_with_dtors::D([B3.3]) (CXXFunctionalCastExpr, ConstructorConversion, class temporary_object_expr_with_dtors::D) // CXX17: [B4] @@ -680,7 +680,7 @@ void referenceVariableWithTernaryOperato // CHECK: void referenceWithFunctionalCast() // CHECK: 1: 1 -// CHECK-NEXT: 2: [B1.1] (CXXConstructExpr, [B1.3], [B1.5], class temporary_object_expr_with_dtors::D) +// CHECK-NEXT: 2: [B1.1] (CXXConstructExpr, [B1.5], class temporary_object_expr_with_dtors::D) // CHECK-NEXT: 3: [B1.2] (BindTemporary) // CHECK-NEXT: 4: temporary_object_expr_with_dtors::D([B1.3]) (CXXFunctionalCastExpr, ConstructorCon // CHECK-NEXT: 5: [B1.4] 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=335798&r1=335797&r2=335798&view=diff ============================================================================== --- cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp (original) +++ cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp Wed Jun 27 17:18:52 2018 @@ -857,7 +857,7 @@ const C &bar3(bool coin) { // 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], [B10.3], class A) +// ANALYZER: 5: [B11.4] (CXXConstructExpr, [B10.3], class A) // CHECK: 6: [B11.5] (BindTemporary) // CHECK: Preds (1): B13 // CHECK: Succs (1): B10 @@ -878,7 +878,7 @@ const C &bar3(bool coin) { // 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], [B10.3], class A) +// ANALYZER: 14: [B12.13] (CXXConstructExpr, [B10.3], class A) // CHECK: 15: [B12.14] (BindTemporary) // CHECK: Preds (1): B13 // CHECK: Succs (1): B10 @@ -1104,7 +1104,7 @@ const C &bar3(bool coin) { // CHECK: Succs (1): B1 // CHECK: [B1] // WARNINGS: 1: A() (CXXConstructExpr, class A) -// ANALYZER: 1: A() (CXXConstructExpr, [B1.2], [B1.4], class A) +// ANALYZER: 1: A() (CXXConstructExpr, [B1.4], class A) // CHECK: 2: [B1.1] (BindTemporary) // CHECK: 3: [B1.2] (ImplicitCastExpr, NoOp, const class A) // CHECK: 4: [B1.3] @@ -1150,7 +1150,7 @@ const C &bar3(bool coin) { // CHECK: 1: A::make // CHECK: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class A (*)(void)) // WARNINGS: 3: [B1.2]() -// ANALYZER: 3: [B1.2]() (CXXRecordTypedCall, [B1.4], [B1.6]) +// ANALYZER: 3: [B1.2]() (CXXRecordTypedCall, [B1.6]) // CHECK: 4: [B1.3] (BindTemporary) // CHECK: 5: [B1.4] (ImplicitCastExpr, NoOp, const class A) // CHECK: 6: [B1.5] _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits