When throwing an elidable object, first try to treat the subexpression

as an rvalue per C++0x [class.copy]p33. If that fails, try again with
the original subexpression.

llvm-svn: 124002
This commit is contained in:
Douglas Gregor 2011-01-21 22:46:35 +00:00
parent f694a55736
commit c74edc272e
2 changed files with 12 additions and 5 deletions

View File

@ -517,13 +517,14 @@ bool Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *&E) {
// Initialize the exception result. This implicitly weeds out
// abstract types or types with inaccessible copy constructors.
const VarDecl *NRVOVariable = getCopyElisionCandidate(QualType(), E, false);
// FIXME: Determine whether we can elide this copy per C++0x [class.copy]p32.
InitializedEntity Entity =
InitializedEntity::InitializeException(ThrowLoc, E->getType(),
/*NRVO=*/false);
ExprResult Res = PerformCopyInitialization(Entity,
SourceLocation(),
Owned(E));
InitializedEntity::InitializeException(ThrowLoc, E->getType(),
/*NRVO=*/false);
ExprResult Res = PerformMoveOrCopyInitialization(Entity, NRVOVariable,
QualType(), E);
if (Res.isInvalid())
return true;
E = Res.takeAs<Expr>();

View File

@ -16,4 +16,10 @@ X return_by_move(int i, X x) {
else
return x;
}
void throw_move_only(X x) {
X x2;
throw x;
throw x2;
}