diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 4605d04e6bb2fb9076bf2058af17912f23e371e6..4e77d33b08dc0eb62895718ce35d34dc2a8409f7 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,17 @@
+2009-12-15  Jonathan Wakely  <jwakely.gcc@gmail.com>
+
+	* include/std/future (unique_future::get, promise::set_value): Remove
+	workaround for c++/34022.
+	(packaged_task::get_future, packaged_task::operator()): Use
+	__throw_bad_function_call.
+	* testsuite/30_threads/packaged_task/cons/assign_neg.cc: Adjust.
+	* testsuite/30_threads/packaged_task/cons/copy_neg.cc: Likewise.
+	* testsuite/30_threads/promise/cons/assign_neg.cc: Likewise.
+	* testsuite/30_threads/promise/cons/copy_neg.cc: Likewise.
+	* testsuite/30_threads/shared_future/cons/assign_neg.cc: Likewise.
+	* testsuite/30_threads/unique_future/cons/assign_neg.cc: Likewise.
+	* testsuite/30_threads/unique_future/cons/copy_neg.cc: Likewise.
+
 2009-12-15  Jonathan Wakely  <jwakely.gcc@gmail.com>
 
 	* include/std/functional (function::function): Move construct target.
diff --git a/libstdc++-v3/include/std/future b/libstdc++-v3/include/std/future
index b8c54b6075f782395d8da5b1746415e24de3e5ea..8f9975dea1a496aa9bd5e0f348c151434962899f 100644
--- a/libstdc++-v3/include/std/future
+++ b/libstdc++-v3/include/std/future
@@ -42,6 +42,7 @@
 #include <system_error>
 #include <exception>
 #include <cstdatomic>
+#include <bits/functexcept.h>
 
 namespace std
 {
@@ -172,7 +173,7 @@ namespace std
 	void
 	_M_set(_Res&& __res)
 	{
-	  ::new (_M_addr()) _Res(_Move_result<_Res>::_S_move(__res));
+	  ::new (_M_addr()) _Res(std::move(__res));
 	  _M_initialized = true;
 	}
 
@@ -183,27 +184,6 @@ namespace std
     };
 
 
-    /// Workaround for CWG issue 664 and c++/34022
-    template<typename _Res, bool = is_scalar<_Res>::value>
-      struct _Move_result;
-
-     /// Specialization for scalar types returns rvalue not rvalue-reference.
-    template<typename _Res>
-      struct _Move_result<_Res, true>
-      {
-	typedef _Res __rval_type;
-	static _Res _S_move(_Res __res) { return __res; }
-      };
-    
-    /// Specialization for non-scalar types returns rvalue-reference.
-    template<typename _Res>
-      struct _Move_result<_Res, false>
-      {
-	typedef _Res&& __rval_type;
-	static _Res&& _S_move(_Res& __res) { return std::move(__res); }
-      };
-
-
     // TODO: use template alias when available
     /*
       template<typename _Res>
@@ -426,7 +406,6 @@ namespace std
 
       typedef __basic_future<_Res> _Base_type;
       typedef typename _Base_type::__state_type __state_type;
-      typedef __future_base::_Move_result<_Res> _Mover;
 
       explicit
       unique_future(const __state_type& __state) : _Base_type(__state) { }
@@ -440,9 +419,9 @@ namespace std
       unique_future& operator=(const unique_future&) = delete;
 
       /// Retrieving the value
-      typename _Mover::__rval_type
+      _Res&&
       get()
-      { return _Mover::_S_move(this->_M_get_result()._M_value()); }
+      { return std::move(this->_M_get_result()._M_value()); }
     };
  
   /// Partial specialization for unique_future<R&>
@@ -586,7 +565,6 @@ namespace std
       template<typename> friend class packaged_task;
 
       typedef __future_base::_State 		_State;
-      typedef __future_base::_Move_result<_Res>	_Mover;
       typedef __future_base::_Result<_Res>	result_type;
       
       shared_ptr<_State>                        _M_future;
@@ -654,7 +632,7 @@ namespace std
       set_value(_Res&& __r)
       {
         if (!_M_satisfied())
-          _M_storage->_M_set(_Mover::_S_move(__r));
+          _M_storage->_M_set(std::move(__r));
         _M_future->_M_set_result(std::move(_M_storage));
       }
 
@@ -940,11 +918,9 @@ namespace std
         }
         __catch (const future_error& __e)
         {
-#ifdef __EXCEPTIONS
           if (__e.code() == future_errc::future_already_retrieved)
-	    throw std::bad_function_call();
-	  throw;
-#endif
+            __throw_bad_function_call();
+          __throw_exception_again;
         }
       }
 
@@ -953,13 +929,7 @@ namespace std
       operator()(_ArgTypes... __args)
       {
         if (!static_cast<bool>(_M_task) || _M_promise._M_satisfied())
-	  {
-#ifdef __EXCEPTIONS
-	    throw std::bad_function_call();
-#else
-	    __builtin_abort();
-#endif
-	  }
+          __throw_bad_function_call();
 
         __try
         {
diff --git a/libstdc++-v3/testsuite/30_threads/packaged_task/cons/assign_neg.cc b/libstdc++-v3/testsuite/30_threads/packaged_task/cons/assign_neg.cc
index db3baf357727cb0bd905b37a7a4314f5dd70b3f4..031ce0ba38e846805b926a9a1ee6a4465941a164 100644
--- a/libstdc++-v3/testsuite/30_threads/packaged_task/cons/assign_neg.cc
+++ b/libstdc++-v3/testsuite/30_threads/packaged_task/cons/assign_neg.cc
@@ -33,4 +33,4 @@ void test01()
 }
 
 // { dg-error "used here" "" { target *-*-* } 32 }
-// { dg-error "deleted function" "" { target *-*-* } 912 }
+// { dg-error "deleted function" "" { target *-*-* } 890 }
diff --git a/libstdc++-v3/testsuite/30_threads/packaged_task/cons/copy_neg.cc b/libstdc++-v3/testsuite/30_threads/packaged_task/cons/copy_neg.cc
index 8e57d3198f458ec130b84f4cb55fcb076df37598..65cf9fdbf9c909ce029f26ac670ab88d0731db60 100644
--- a/libstdc++-v3/testsuite/30_threads/packaged_task/cons/copy_neg.cc
+++ b/libstdc++-v3/testsuite/30_threads/packaged_task/cons/copy_neg.cc
@@ -32,4 +32,4 @@ void test01()
 }
 
 // { dg-error "used here" "" { target *-*-* } 31 }
-// { dg-error "deleted function" "" { target *-*-* } 911 }
+// { dg-error "deleted function" "" { target *-*-* } 889 }
diff --git a/libstdc++-v3/testsuite/30_threads/promise/cons/assign_neg.cc b/libstdc++-v3/testsuite/30_threads/promise/cons/assign_neg.cc
index 5e16d145ccc53f86afbbaf6e5df98d95923890d6..54347408c530f6eeaee9e6c26cf78b8ecfef33dd 100644
--- a/libstdc++-v3/testsuite/30_threads/promise/cons/assign_neg.cc
+++ b/libstdc++-v3/testsuite/30_threads/promise/cons/assign_neg.cc
@@ -33,4 +33,4 @@ void test01()
 }
 
 // { dg-error "used here" "" { target *-*-* } 32 }
-// { dg-error "deleted function" "" { target *-*-* } 630 }
+// { dg-error "deleted function" "" { target *-*-* } 608 }
diff --git a/libstdc++-v3/testsuite/30_threads/promise/cons/copy_neg.cc b/libstdc++-v3/testsuite/30_threads/promise/cons/copy_neg.cc
index 1e857977927f665c8eac3a118f001d60f5106d78..79d2e16639fa73a067ff5739a78700ccf83af4a0 100644
--- a/libstdc++-v3/testsuite/30_threads/promise/cons/copy_neg.cc
+++ b/libstdc++-v3/testsuite/30_threads/promise/cons/copy_neg.cc
@@ -32,4 +32,4 @@ void test01()
 }
 
 // { dg-error "used here" "" { target *-*-* } 31 }
-// { dg-error "deleted function" "" { target *-*-* } 614 }
+// { dg-error "deleted function" "" { target *-*-* } 592 }
diff --git a/libstdc++-v3/testsuite/30_threads/shared_future/cons/assign_neg.cc b/libstdc++-v3/testsuite/30_threads/shared_future/cons/assign_neg.cc
index 26211fe1c7629eaeb0ccea5e6d40deb1a9610a24..0f284cd0a262d2cfcef0ccec9cab031115684c8c 100644
--- a/libstdc++-v3/testsuite/30_threads/shared_future/cons/assign_neg.cc
+++ b/libstdc++-v3/testsuite/30_threads/shared_future/cons/assign_neg.cc
@@ -35,4 +35,4 @@ void test01()
 }
 
 // { dg-error "used here" "" { target *-*-* } 34 }
-// { dg-error "deleted function" "" { target *-*-* } 514 }
+// { dg-error "deleted function" "" { target *-*-* } 493 }
diff --git a/libstdc++-v3/testsuite/30_threads/unique_future/cons/assign_neg.cc b/libstdc++-v3/testsuite/30_threads/unique_future/cons/assign_neg.cc
index e29148ee78588829a95abc75cf22001571143a57..69caf12edb4fc266eabb5be70aaaa28420388be9 100644
--- a/libstdc++-v3/testsuite/30_threads/unique_future/cons/assign_neg.cc
+++ b/libstdc++-v3/testsuite/30_threads/unique_future/cons/assign_neg.cc
@@ -35,4 +35,4 @@ void test01()
 }
 
 // { dg-error "used here" "" { target *-*-* } 34 }
-// { dg-error "deleted function" "" { target *-*-* } 440 }
+// { dg-error "deleted function" "" { target *-*-* } 419 }
diff --git a/libstdc++-v3/testsuite/30_threads/unique_future/cons/copy_neg.cc b/libstdc++-v3/testsuite/30_threads/unique_future/cons/copy_neg.cc
index 8134c7d9219d99e718ccabed07688856f486e5f8..43e940cfa76e067b4365e2d163180eb57869487a 100644
--- a/libstdc++-v3/testsuite/30_threads/unique_future/cons/copy_neg.cc
+++ b/libstdc++-v3/testsuite/30_threads/unique_future/cons/copy_neg.cc
@@ -34,4 +34,4 @@ void test01()
 }
 
 // { dg-error "used here" "" { target *-*-* } 33 }
-// { dg-error "deleted function" "" { target *-*-* } 439 }
+// { dg-error "deleted function" "" { target *-*-* } 418 }