diff options
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/Sema.h | 4 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 5 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 15 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 7 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateExpr.cpp | 5 |
5 files changed, 28 insertions, 8 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 34513e7d588..28fb918fefa 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/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/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 8f64e78c522..70057a34dfb 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/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/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index c01c812be60..c0469416e42 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/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/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index ed4ac555add..7353efbae7d 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/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/clang/lib/Sema/SemaTemplateInstantiateExpr.cpp b/clang/lib/Sema/SemaTemplateInstantiateExpr.cpp index 3c67f2ad0d3..bf19701d6be 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateExpr.cpp +++ b/clang/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 |

