r324952 - [CFG] Provide construction contexts for return value constructors.

Artem Dergachev via cfe-commits cfe-commits at lists.llvm.org
Mon Feb 12 14:36:36 PST 2018


Author: dergachev
Date: Mon Feb 12 14:36:36 2018
New Revision: 324952

URL: http://llvm.org/viewvc/llvm-project?rev=324952&view=rev
Log:
[CFG] Provide construction contexts for return value constructors.

When the current function returns a C++ object by value, CFG elements for
constructors that construct the return values can now be queried to discover
that they're indeed participating in construction of the respective return value
at the respective return statement.

Differential Revision: https://reviews.llvm.org/D42875

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=324952&r1=324951&r2=324952&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CFG.cpp (original)
+++ cfe/trunk/lib/Analysis/CFG.cpp Mon Feb 12 14:36:36 2018
@@ -2575,6 +2575,8 @@ CFGBlock *CFGBuilder::VisitReturnStmt(Re
 
   addAutomaticObjHandling(ScopePos, LocalScope::const_iterator(), R);
 
+  EnterConstructionContextIfNecessary(R, R->getRetValue());
+
   // If the one of the destructors does not return, we already have the Exit
   // block as a successor.
   if (!Block->hasNoReturnElement())

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=324952&r1=324951&r2=324952&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/cfg-rich-constructors.cpp (original)
+++ cfe/trunk/test/Analysis/cfg-rich-constructors.cpp Mon Feb 12 14:36:36 2018
@@ -5,6 +5,7 @@ class C {
 public:
   C();
   C(C *);
+  C(int, int);
 
   static C get();
 };
@@ -224,3 +225,94 @@ public:
 };
 
 } // end namespace ctor_initializers
+
+namespace return_stmt {
+
+// CHECK: C returnVariable()
+// CHECK:          1:  (CXXConstructExpr, [B1.2], class C)
+// CHECK-NEXT:     2: C c;
+// CHECK-NEXT:     3: c
+// CHECK-NEXT:     4: [B1.3] (ImplicitCastExpr, NoOp, class C)
+// CHECK-NEXT:     5: [B1.4] (CXXConstructExpr, [B1.6], class C)
+// CHECK-NEXT:     6: return [B1.5];
+C returnVariable() {
+  C c;
+  return c;
+}
+
+// CHECK: C returnEmptyBraces()
+// CHECK:          1: {} (CXXConstructExpr, [B1.2], class C)
+// CHECK-NEXT:     2: return [B1.1];
+C returnEmptyBraces() {
+  return {};
+}
+
+// CHECK: C returnBracesWithOperatorNew()
+// CHECK:          1: CFGNewAllocator(C *)
+// CHECK-NEXT:     2:  (CXXConstructExpr, [B1.3], class C)
+// CHECK-NEXT:     3: new C([B1.2])
+// CHECK-NEXT:     4: {[B1.3]} (CXXConstructExpr, [B1.5], class C)
+// CHECK-NEXT:     5: return [B1.4];
+C returnBracesWithOperatorNew() {
+  return {new C()};
+}
+
+// CHECK: C returnBracesWithMultipleItems()
+// CHECK:          1: 123
+// CHECK-NEXT:     2: 456
+// CHECK-NEXT:     3: {[B1.1], [B1.2]} (CXXConstructExpr, [B1.4], class C)
+// CHECK-NEXT:     4: return [B1.3];
+C returnBracesWithMultipleItems() {
+  return {123, 456};
+}
+
+// TODO: Should find construction targets for the first constructor as well.
+// CHECK: C returnTemporary()
+// CHECK:          1: C() (CXXConstructExpr, class C)
+// CHECK-NEXT:     2: [B1.1]
+// CHECK-NEXT:     3: [B1.2] (CXXConstructExpr, [B1.4], class C)
+// CHECK-NEXT:     4: return [B1.3];
+C returnTemporary() {
+  return C();
+}
+
+// TODO: Should find construction targets for the first constructor as well.
+// CHECK: C returnTemporaryWithArgument()
+// CHECK:          1: nullptr
+// CHECK-NEXT:     2: [B1.1] (ImplicitCastExpr, NullToPointer, class C *)
+// CHECK-NEXT:     3: [B1.2] (CXXConstructExpr, class C)
+// CHECK-NEXT:     4: C([B1.3]) (CXXFunctionalCastExpr, ConstructorConversion, class C)
+// CHECK-NEXT:     5: [B1.4]
+// CHECK-NEXT:     6: [B1.5] (CXXConstructExpr, [B1.7], class C)
+// CHECK-NEXT:     7: return [B1.6];
+C returnTemporaryWithArgument() {
+  return C(nullptr);
+}
+
+// CHECK: C returnTemporaryConstructedByFunction()
+// CHECK:          1: C::get
+// CHECK-NEXT:     2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void))
+// CHECK-NEXT:     3: [B1.2]()
+// CHECK-NEXT:     4: [B1.3]
+// CHECK-NEXT:     5: [B1.4] (CXXConstructExpr, [B1.6], class C)
+// CHECK-NEXT:     6: return [B1.5];
+C returnTemporaryConstructedByFunction() {
+  return C::get();
+}
+
+// TODO: Should find construction targets for the first constructor as well.
+// CHECK: C returnChainOfCopies()
+// CHECK:          1: C::get
+// CHECK-NEXT:     2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class C (*)(void))
+// CHECK-NEXT:     3: [B1.2]()
+// CHECK-NEXT:     4: [B1.3]
+// CHECK-NEXT:     5: [B1.4] (CXXConstructExpr, class C)
+// CHECK-NEXT:     6: C([B1.5]) (CXXFunctionalCastExpr, ConstructorConversion, class C)
+// CHECK-NEXT:     7: [B1.6]
+// CHECK-NEXT:     8: [B1.7] (CXXConstructExpr, [B1.9], class C)
+// CHECK-NEXT:     9: return [B1.8];
+C returnChainOfCopies() {
+  return C(C::get());
+}
+
+} // end namespace return_stmt

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=324952&r1=324951&r2=324952&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp (original)
+++ cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp Mon Feb 12 14:36:36 2018
@@ -220,7 +220,8 @@ int testConsistencyNestedNormalReturn(bo
 // CHECK:     2: [B1.1] (BindTemporary)
 // CHECK:     3: [B1.2] (ImplicitCastExpr, NoOp, const class A)
 // CHECK:     4: [B1.3]
-// CHECK:     5: [B1.4] (CXXConstructExpr, class A)
+// WARNINGS:     5: [B1.4] (CXXConstructExpr, class A)
+// ANALYZER:     5: [B1.4] (CXXConstructExpr, [B1.7], class A)
 // CHECK:     6: ~A() (Temporary object destructor)
 // CHECK:     7: return [B1.5];
 // CHECK:     Preds (1): B2
@@ -278,7 +279,8 @@ int testConsistencyNestedNormalReturn(bo
 // CHECK:     2: [B1.1] (BindTemporary)
 // CHECK:     3: [B1.2] (ImplicitCastExpr, NoOp, const class A)
 // CHECK:     4: [B1.3]
-// CHECK:     5: [B1.4] (CXXConstructExpr, class A)
+// WARNINGS:     5: [B1.4] (CXXConstructExpr, class A)
+// ANALYZER:     5: [B1.4] (CXXConstructExpr, [B1.7], class A)
 // CHECK:     6: ~A() (Temporary object destructor)
 // CHECK:     7: return [B1.5];
 // CHECK:     Preds (1): B2




More information about the cfe-commits mailing list