[cfe-commits] r73462 - in /cfe/trunk: include/clang/AST/ExprCXX.h lib/AST/ExprCXX.cpp lib/CodeGen/CGCXXTemp.cpp lib/Sema/Sema.h lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaTemplateInstantiateExpr.cpp test/CodeGenCXX/default-arg-temps.cpp

Anders Carlsson andersca at mac.com
Mon Jun 15 20:37:31 PDT 2009


Author: andersca
Date: Mon Jun 15 22:37:31 2009
New Revision: 73462

URL: http://llvm.org/viewvc/llvm-project?rev=73462&view=rev
Log:
Handle temporaries in default arguments.

Added:
    cfe/trunk/test/CodeGenCXX/default-arg-temps.cpp
Modified:
    cfe/trunk/include/clang/AST/ExprCXX.h
    cfe/trunk/lib/AST/ExprCXX.cpp
    cfe/trunk/lib/CodeGen/CGCXXTemp.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp

Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=73462&r1=73461&r2=73462&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Mon Jun 15 22:37:31 2009
@@ -1023,17 +1023,16 @@
   CXXTemporary **Temps;
   unsigned NumTemps;
 
-  bool DestroyTemps;
+  bool ShouldDestroyTemps;
   
   CXXExprWithTemporaries(Expr *SubExpr, CXXTemporary **Temps, 
-                         unsigned NumTemps, bool DestroyTemps);
+                         unsigned NumTemps, bool ShouldDestroyTemps);
   ~CXXExprWithTemporaries();
   
 public:
   static CXXExprWithTemporaries *Create(ASTContext &C, Expr *SubExpr,
-                                        CXXTemporary **Temps, 
-                                        unsigned NumTemps,
-                                        bool DestroyTems);
+                                        CXXTemporary **Temps, unsigned NumTemps,
+                                        bool ShouldDestroyTemporaries);
   void Destroy(ASTContext &C);
   
   unsigned getNumTemporaries() const { return NumTemps; }
@@ -1046,6 +1045,8 @@
     return Temps[i];
   }
   
+  bool shouldDestroyTemporaries() const { return ShouldDestroyTemps; }
+  
   void removeLastTemporary() { NumTemps--; }
   
   Expr *getSubExpr() { return cast<Expr>(SubExpr); }

Modified: cfe/trunk/lib/AST/ExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprCXX.cpp?rev=73462&r1=73461&r2=73462&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ExprCXX.cpp (original)
+++ cfe/trunk/lib/AST/ExprCXX.cpp Mon Jun 15 22:37:31 2009
@@ -306,10 +306,11 @@
 CXXExprWithTemporaries::CXXExprWithTemporaries(Expr *subexpr, 
                                                CXXTemporary **temps, 
                                                unsigned numtemps,
-                                               bool destroytemps)
+                                               bool shoulddestroytemps)
 : Expr(CXXExprWithTemporariesClass, subexpr->getType(),
        subexpr->isTypeDependent(), subexpr->isValueDependent()), 
-  SubExpr(subexpr), Temps(0), NumTemps(numtemps), DestroyTemps(destroytemps) {
+  SubExpr(subexpr), Temps(0), NumTemps(numtemps), 
+  ShouldDestroyTemps(shoulddestroytemps) {
   if (NumTemps > 0) {
     Temps = new CXXTemporary*[NumTemps];
     for (unsigned i = 0; i < NumTemps; ++i)
@@ -321,9 +322,9 @@
                                                        Expr *SubExpr,
                                                        CXXTemporary **Temps, 
                                                        unsigned NumTemps,
-                                                       bool DestroyTemps) {
+                                                       bool ShouldDestroyTemps){
   return new (C) CXXExprWithTemporaries(SubExpr, Temps, NumTemps, 
-                                        DestroyTemps);
+                                        ShouldDestroyTemps);
 }
 
 void CXXExprWithTemporaries::Destroy(ASTContext &C) {

Modified: cfe/trunk/lib/CodeGen/CGCXXTemp.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXTemp.cpp?rev=73462&r1=73461&r2=73462&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXXTemp.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXXTemp.cpp Mon Jun 15 22:37:31 2009
@@ -85,6 +85,11 @@
 CodeGenFunction::EmitCXXExprWithTemporaries(const CXXExprWithTemporaries *E,
                                             llvm::Value *AggLoc,
                                             bool isAggLocVolatile) {
+  // If we shouldn't destroy the temporaries, just emit the
+  // child expression.
+  if (!E->shouldDestroyTemporaries())
+    return EmitAnyExpr(E->getSubExpr(), AggLoc, isAggLocVolatile);
+
   // Keep track of the current cleanup stack depth.
   size_t CleanupStackDepth = CleanupEntries.size();
   (void) CleanupStackDepth;

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=73462&r1=73461&r2=73462&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Mon Jun 15 22:37:31 2009
@@ -1661,8 +1661,8 @@
   /// MaybeCreateCXXExprWithTemporaries - If the list of temporaries is 
   /// non-empty, will create a new CXXExprWithTemporaries expression.
   /// Otherwise, just returs the passed in expression.
-  Expr *MaybeCreateCXXExprWithTemporaries(Expr *SubExpr, 
-                                          bool DestroyTemps = true);
+  Expr *MaybeCreateCXXExprWithTemporaries(Expr *SubExpr,
+                                          bool ShouldDestroyTemporaries);
   
   virtual OwningExprResult ActOnFinishFullExpr(ExprArg Expr);
 

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=73462&r1=73461&r2=73462&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Jun 15 22:37:31 2009
@@ -147,8 +147,11 @@
     return;
   }
 
+  DefaultArgPtr = MaybeCreateCXXExprWithTemporaries(DefaultArg.take(),
+                                                    /*DestroyTemps=*/false);
+  
   // Okay: add the default argument to the parameter
-  Param->setDefaultArg(DefaultArg.take());
+  Param->setDefaultArg(DefaultArgPtr);
 }
 
 /// ActOnParamUnparsedDefaultArgument - We've seen a default

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=73462&r1=73461&r2=73462&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Jun 15 22:37:31 2009
@@ -2491,8 +2491,21 @@
         FDecl << cast<CXXRecordDecl>(FDecl->getDeclContext())->getDeclName();
         Diag(UnparsedDefaultArgLocs[FDecl->getParamDecl(i)], 
               diag::note_default_argument_declared_here);
+      } else {
+        Expr *DefaultExpr = FDecl->getParamDecl(i)->getDefaultArg();
+        
+        // If the default expression creates temporaries, we need to
+        // push them to the current stack of expression temporaries so they'll
+        // be properly destroyed.
+        if (CXXExprWithTemporaries *E 
+              = dyn_cast_or_null<CXXExprWithTemporaries>(DefaultExpr)) {
+          assert(!E->shouldDestroyTemporaries() && 
+                 "Can't destroy temporaries in a default argument expr!");
+          for (unsigned I = 0, N = E->getNumTemporaries(); I != N; ++I)
+            ExprTemporaries.push_back(E->getTemporary(I));
+        }
       }
-      
+  
       // We already type-checked the argument, so we know it works.
       Arg = new (Context) CXXDefaultArgExpr(FDecl->getParamDecl(i));
     }

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=73462&r1=73461&r2=73462&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Mon Jun 15 22:37:31 2009
@@ -1589,7 +1589,7 @@
 }
 
 Expr *Sema::MaybeCreateCXXExprWithTemporaries(Expr *SubExpr, 
-                                              bool DestroyTemps) {
+                                              bool ShouldDestroyTemps) {
   assert(SubExpr && "sub expression can't be null!");
   
   if (ExprTemporaries.empty())
@@ -1598,7 +1598,7 @@
   Expr *E = CXXExprWithTemporaries::Create(Context, SubExpr,
                                            &ExprTemporaries[0], 
                                            ExprTemporaries.size(),
-                                           DestroyTemps);
+                                           ShouldDestroyTemps);
   ExprTemporaries.clear();
   
   return E;
@@ -1607,7 +1607,8 @@
 Sema::OwningExprResult Sema::ActOnFinishFullExpr(ExprArg Arg) {
   Expr *FullExpr = Arg.takeAs<Expr>();
   if (FullExpr)
-    FullExpr = MaybeCreateCXXExprWithTemporaries(FullExpr);
+    FullExpr = MaybeCreateCXXExprWithTemporaries(FullExpr, 
+                                                 /*ShouldDestroyTemps=*/true);
 
   return Owned(FullExpr);
 }

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp?rev=73462&r1=73461&r2=73462&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp Mon Jun 15 22:37:31 2009
@@ -1165,7 +1165,10 @@
   if (SubExpr.isInvalid())
     return SemaRef.ExprError();
 
-  return SemaRef.ActOnFinishFullExpr(move(SubExpr));
+  Expr *Temp = 
+    SemaRef.MaybeCreateCXXExprWithTemporaries(SubExpr.takeAs<Expr>(),
+                                              E->shouldDestroyTemporaries());
+  return SemaRef.Owned(Temp);
 }
 
 Sema::OwningExprResult 

Added: cfe/trunk/test/CodeGenCXX/default-arg-temps.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/default-arg-temps.cpp?rev=73462&view=auto

==============================================================================
--- cfe/trunk/test/CodeGenCXX/default-arg-temps.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/default-arg-temps.cpp Mon Jun 15 22:37:31 2009
@@ -0,0 +1,15 @@
+// RUN: clang-cc -emit-llvm %s -o %t -triple=x86_64-apple-darwin9 && 
+
+struct T {
+  T();
+  ~T();
+};
+
+void f(const T& t = T());
+
+void g() {
+  // RUN: grep "call void @_ZN1TC1Ev" %t | count 2 &&
+  // RUN: grep "call void @_ZN1TD1Ev" %t | count 2
+  f();
+  f();
+}





More information about the cfe-commits mailing list