[PATCH] Fix some cases of incorrect handling of lifetime extended temporaries.

Manuel Klimek klimek at google.com
Mon Jul 28 07:42:26 PDT 2014


Hi jordan_rose,

MaterializeTemporaryExpr already contains information about the lifetime
of the temporary; if the lifetime is not the full statement, we do not
want to emit a destructor at the end of the full statement for it.

http://reviews.llvm.org/D4696

Files:
  lib/Analysis/CFG.cpp

Index: lib/Analysis/CFG.cpp
===================================================================
--- lib/Analysis/CFG.cpp
+++ lib/Analysis/CFG.cpp
@@ -1000,21 +1000,17 @@
   if (!BuildOpts.AddInitializers)
     return Block;
 
-  bool IsReference = false;
   bool HasTemporaries = false;
 
   // Destructors of temporaries in initialization expression should be called
   // after initialization finishes.
   Expr *Init = I->getInit();
   if (Init) {
-    if (FieldDecl *FD = I->getAnyMember())
-      IsReference = FD->getType()->isReferenceType();
     HasTemporaries = isa<ExprWithCleanups>(Init);
 
     if (BuildOpts.AddTemporaryDtors && HasTemporaries) {
       // Generate destructors for temporaries in initialization expression.
-      VisitForTemporaryDtors(cast<ExprWithCleanups>(Init)->getSubExpr(),
-          IsReference);
+      VisitForTemporaryDtors(cast<ExprWithCleanups>(Init)->getSubExpr());
     }
   }
 
@@ -1946,7 +1942,6 @@
     return Block;
   }
 
-  bool IsReference = false;
   bool HasTemporaries = false;
 
   // Guard static initializers under a branch.
@@ -1968,13 +1963,11 @@
   // after initialization finishes.
   Expr *Init = VD->getInit();
   if (Init) {
-    IsReference = VD->getType()->isReferenceType();
     HasTemporaries = isa<ExprWithCleanups>(Init);
 
     if (BuildOpts.AddTemporaryDtors && HasTemporaries) {
       // Generate destructors for temporaries in initialization expression.
-      VisitForTemporaryDtors(cast<ExprWithCleanups>(Init)->getSubExpr(),
-          IsReference);
+      VisitForTemporaryDtors(cast<ExprWithCleanups>(Init)->getSubExpr());
     }
   }
 
@@ -3492,13 +3485,21 @@
       E = cast<CastExpr>(E)->getSubExpr();
       goto tryAgain;
 
+    case Stmt::CXXFunctionalCastExprClass:
+      // For functional cast we want BindToTemporary to be passed further.
+      E = cast<CXXFunctionalCastExpr>(E)->getSubExpr();
+      goto tryAgain;
+
     case Stmt::ParenExprClass:
       E = cast<ParenExpr>(E)->getSubExpr();
       goto tryAgain;
 
-    case Stmt::MaterializeTemporaryExprClass:
+    case Stmt::MaterializeTemporaryExprClass: {
+      const MaterializeTemporaryExpr* MTE = cast<MaterializeTemporaryExpr>(E);
+      BindToTemporary = (MTE->getStorageDuration() != SD_FullExpression);
       E = cast<MaterializeTemporaryExpr>(E)->GetTemporaryExpr();
       goto tryAgain;
+    }
 
     case Stmt::BlockExprClass:
       // Don't recurse into blocks; their subexpressions don't get evaluated
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D4696.11944.patch
Type: text/x-patch
Size: 2472 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140728/28775111/attachment.bin>


More information about the cfe-commits mailing list