]> granicus.if.org Git - clang/commitdiff
When throwing an elidable object, first try to treat the subexpression
authorDouglas Gregor <dgregor@apple.com>
Fri, 21 Jan 2011 22:46:35 +0000 (22:46 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 21 Jan 2011 22:46:35 +0000 (22:46 +0000)
as an rvalue per C++0x [class.copy]p33. If that fails, try again with
the original subexpression.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124002 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExprCXX.cpp
test/CXX/special/class.copy/p33-0x.cpp

index 2e5204f2584ed8870e195956e261eb7b3d2f0b2c..0b7a051365e1d9bb2b2a7ca6b3499d0de0d15161 100644 (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>();
index a9ce58937a65db68b0740823d2a32a938abb3103..38eb7adb38b016d9c7376c1da3803498a124ae5d 100644 (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;
+}