diff options
author | Anders Carlsson <andersca@mac.com> | 2009-06-16 03:37:31 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2009-06-16 03:37:31 +0000 |
commit | f54741e6465692d3bdbae974ac3beeeab92e4a95 (patch) | |
tree | 1b7100f044e74fc9da1164e514b784b5285b5850 /lib | |
parent | 76e4ce42a30cee4dc40ce7c6014874fbc4f9baa7 (diff) |
Handle temporaries in default arguments.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@73462 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ExprCXX.cpp | 9 | ||||
-rw-r--r-- | lib/CodeGen/CGCXXTemp.cpp | 5 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 4 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 5 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 15 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 7 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateExpr.cpp | 5 |
7 files changed, 38 insertions, 12 deletions
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp index 8fd66a2981..18c0f77ab2 100644 --- a/lib/AST/ExprCXX.cpp +++ b/lib/AST/ExprCXX.cpp @@ -306,10 +306,11 @@ void CXXConstructExpr::Destroy(ASTContext &C) { 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 @@ CXXExprWithTemporaries *CXXExprWithTemporaries::Create(ASTContext &C, Expr *SubExpr, CXXTemporary **Temps, unsigned NumTemps, - bool DestroyTemps) { + bool ShouldDestroyTemps){ return new (C) CXXExprWithTemporaries(SubExpr, Temps, NumTemps, - DestroyTemps); + ShouldDestroyTemps); } void CXXExprWithTemporaries::Destroy(ASTContext &C) { diff --git a/lib/CodeGen/CGCXXTemp.cpp b/lib/CodeGen/CGCXXTemp.cpp index 141726a649..a6e6d11505 100644 --- a/lib/CodeGen/CGCXXTemp.cpp +++ b/lib/CodeGen/CGCXXTemp.cpp @@ -85,6 +85,11 @@ RValue 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; diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 34513e7d58..28fb918fef 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -1661,8 +1661,8 @@ public: /// 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); diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 8f64e78c52..70057a34df 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -147,8 +147,11 @@ Sema::ActOnParamDefaultArgument(DeclPtrTy param, SourceLocation EqualLoc, 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 diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index c01c812be6..c0469416e4 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -2491,8 +2491,21 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, 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)); } diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index ed4ac555ad..7353efbae7 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -1589,7 +1589,7 @@ Expr *Sema::RemoveOutermostTemporaryBinding(Expr *E) { } 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 *Sema::MaybeCreateCXXExprWithTemporaries(Expr *SubExpr, Expr *E = CXXExprWithTemporaries::Create(Context, SubExpr, &ExprTemporaries[0], ExprTemporaries.size(), - DestroyTemps); + ShouldDestroyTemps); ExprTemporaries.clear(); return E; @@ -1607,7 +1607,8 @@ Expr *Sema::MaybeCreateCXXExprWithTemporaries(Expr *SubExpr, Sema::OwningExprResult Sema::ActOnFinishFullExpr(ExprArg Arg) { Expr *FullExpr = Arg.takeAs<Expr>(); if (FullExpr) - FullExpr = MaybeCreateCXXExprWithTemporaries(FullExpr); + FullExpr = MaybeCreateCXXExprWithTemporaries(FullExpr, + /*ShouldDestroyTemps=*/true); return Owned(FullExpr); } diff --git a/lib/Sema/SemaTemplateInstantiateExpr.cpp b/lib/Sema/SemaTemplateInstantiateExpr.cpp index 3c67f2ad0d..bf19701d6b 100644 --- a/lib/Sema/SemaTemplateInstantiateExpr.cpp +++ b/lib/Sema/SemaTemplateInstantiateExpr.cpp @@ -1165,7 +1165,10 @@ TemplateExprInstantiator::VisitCXXExprWithTemporaries( 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 |