Handle temporaries in default arguments.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@73462 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 34513e7..28fb918 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -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);
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 8f64e78..70057a3 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -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
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index c01c812..c046941 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -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));
}
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index ed4ac55..7353efb 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -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);
}
diff --git a/lib/Sema/SemaTemplateInstantiateExpr.cpp b/lib/Sema/SemaTemplateInstantiateExpr.cpp
index 3c67f2a..bf19701 100644
--- a/lib/Sema/SemaTemplateInstantiateExpr.cpp
+++ b/lib/Sema/SemaTemplateInstantiateExpr.cpp
@@ -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