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