r335798 - [CFG] [analyzer] Simplify lifetime-extended temporary construction contexts.

Artem Dergachev via cfe-commits cfe-commits at lists.llvm.org
Wed Jun 27 17:18:52 PDT 2018


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]




More information about the cfe-commits mailing list