Index: gcc/cp/typeck.c =================================================================== --- gcc/cp/typeck.c (revision 140759) +++ gcc/cp/typeck.c (working copy) @@ -4481,6 +4481,10 @@ build_unary_op (enum tree_code code, tre return t; } + case NON_LVALUE_EXPR: + arg = TREE_OPERAND (arg, 0); + break; + default: break; } @@ -5145,6 +5149,12 @@ build_static_cast_1 (tree type, tree exp return build_nop (type, expr); } + /* A value of type D can be explicitly converted to BT&&. */ + if (TREE_CODE (type) == REFERENCE_TYPE + && TYPE_REF_IS_RVALUE (type) + && same_type_p (TREE_TYPE (type), TREE_TYPE (expr))) + return rvalue(expr); + *valid_p = false; return error_mark_node; } Index: gcc/cp/call.c =================================================================== --- gcc/cp/call.c (revision 140759) +++ gcc/cp/call.c (working copy) @@ -1009,6 +1009,11 @@ convert_class_to_reference (tree referen = TYPE_REF_IS_RVALUE (TREE_TYPE (TREE_TYPE (cand->fn))) == TYPE_REF_IS_RVALUE (reference_type); cand->second_conv->bad_p |= cand->convs[0]->bad_p; + + /* Don't allow binding of lvalues to rvalue references. */ + if (TYPE_REF_IS_RVALUE (reference_type) + && !TYPE_REF_IS_RVALUE (TREE_TYPE (TREE_TYPE (cand->fn)))) + return NULL; } } conversions = TREE_CHAIN (conversions); @@ -1191,6 +1196,11 @@ reference_binding (tree rto, tree rfrom, actually occurs. */ conv->need_temporary_p = true; + /* Don't allow binding of lvalues to rvalue references. */ + if (lvalue_p && TYPE_REF_IS_RVALUE (rto) + && !(flags & LOOKUP_PREFER_RVALUE)) + return NULL; + return conv; } /* [class.conv.fct] A conversion function is never used to convert a @@ -1263,9 +1273,13 @@ reference_binding (tree rto, tree rfrom, return NULL; conv = build_conv (ck_ref_bind, rto, conv); - /* This reference binding, unlike those above, requires the - creation of a temporary. */ - conv->need_temporary_p = true; + + if (TREE_CODE (expr) != NON_LVALUE_EXPR) + { + /* This reference binding, unlike those above, requires the + creation of a temporary. */ + conv->need_temporary_p = true; + } conv->rvaluedness_matches_p = TYPE_REF_IS_RVALUE (rto); return conv; Index: libstdc++-v3/include/debug/unordered_map =================================================================== --- libstdc++-v3/include/debug/unordered_map (revision 140759) +++ libstdc++-v3/include/debug/unordered_map (working copy) @@ -101,7 +101,7 @@ namespace __debug } void - swap(unordered_map&& __x) + swap(unordered_map& __x) { _Safe_assoc::swap(__x); _Safe_base::_M_swap(__x); @@ -201,7 +201,7 @@ namespace __debug } void - swap(unordered_multimap&& __x) + swap(unordered_multimap& __x) { _Safe_assoc::swap(__x); _Safe_base::_M_swap(__x); Index: libstdc++-v3/include/debug/unordered_set =================================================================== --- libstdc++-v3/include/debug/unordered_set (revision 140759) +++ libstdc++-v3/include/debug/unordered_set (working copy) @@ -102,7 +102,7 @@ namespace __debug } void - swap(unordered_set&& __x) + swap(unordered_set& __x) { _Safe_assoc::swap(__x); _Safe_base::_M_swap(__x); @@ -199,7 +199,7 @@ namespace __debug } void - swap(unordered_multiset&& __x) + swap(unordered_multiset& __x) { _Safe_assoc::swap(__x); _Safe_base::_M_swap(__x); Index: libstdc++-v3/include/tr1_impl/hashtable =================================================================== --- libstdc++-v3/include/tr1_impl/hashtable (revision 140759) +++ libstdc++-v3/include/tr1_impl/hashtable (working copy) @@ -228,11 +228,7 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1 ~_Hashtable(); -#ifdef _GLIBCXX_INCLUDE_AS_CXX0X - void swap(_Hashtable&&); -#else void swap(_Hashtable&); -#endif // Basic container operations iterator @@ -710,11 +706,7 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1 void _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>:: -#ifdef _GLIBCXX_INCLUDE_AS_CXX0X - swap(_Hashtable&& __x) -#else swap(_Hashtable& __x) -#endif { // The only base class with member variables is hash_code_base. We // define _Hash_code_base::_M_swap because different specializations Index: libstdc++-v3/include/std/tuple =================================================================== --- libstdc++-v3/include/std/tuple (revision 140759) +++ libstdc++-v3/include/std/tuple (working copy) @@ -156,7 +156,7 @@ namespace std : _Inherited(__in._M_tail()), _Base(__in._M_head()) { } _Tuple_impl(_Tuple_impl&& __in) - : _Inherited(std::move<_Inherited&&>(__in._M_tail())), + : _Inherited(std::move<_Inherited&>(__in._M_tail())), _Base(std::forward<_Head>(__in._M_head())) { } template @@ -166,7 +166,7 @@ namespace std template _Tuple_impl(_Tuple_impl<_Idx, _UElements...>&& __in) : _Inherited(std::move:: - _Inherited&&>(__in._M_tail())), + _Inherited&>(__in._M_tail())), _Base(std::forward:: _Base>(__in._M_head())) { } @@ -228,7 +228,7 @@ namespace std : _Inherited(static_cast(__in)) { } tuple(tuple&& __in) - : _Inherited(std::move<_Inherited>(__in)) { } + : _Inherited(std::move<_Inherited&>(__in)) { } template tuple(const tuple<_UElements...>& __in) @@ -237,7 +237,7 @@ namespace std template tuple(tuple<_UElements...>&& __in) - : _Inherited(std::move<_Tuple_impl<0, _UElements...> >(__in)) { } + : _Inherited(std::move<_Tuple_impl<0, _UElements...>&>(__in)) { } // XXX http://gcc.gnu.org/ml/libstdc++/2008-02/msg00047.html template @@ -303,7 +303,7 @@ namespace std : _Inherited(static_cast(__in)) { } tuple(tuple&& __in) - : _Inherited(std::move<_Inherited>(__in)) { } + : _Inherited(std::move<_Inherited&>(__in)) { } template tuple(const tuple<_U1, _U2>& __in) @@ -311,7 +311,7 @@ namespace std template tuple(tuple<_U1, _U2>&& __in) - : _Inherited(std::move<_Tuple_impl<0, _U1, _U2> >(__in)) { } + : _Inherited(std::move<_Tuple_impl<0, _U1, _U2>&>(__in)) { } template tuple(const pair<_U1, _U2>& __in) Index: libstdc++-v3/include/std/iosfwd =================================================================== --- libstdc++-v3/include/std/iosfwd (revision 140759) +++ libstdc++-v3/include/std/iosfwd (working copy) @@ -160,6 +160,30 @@ _GLIBCXX_BEGIN_NAMESPACE(std) #endif /** @} */ +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + // FIXME: these aren't quite right, because we want the return type + // to be the ame type as the stream we get, e.g., we don't want to + // return the base class basic_ostream<_CharT, _Traits>. So, these routines really need to take in an arbitrary type _Stream, check that it's convertible to basic_ostream<_CharT, _Traits + + // Output via an rvalue stream + template + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>&& __stream, const _Tp& __x) + { + __stream << __x; + return __stream; + } + + // Input via an rvalue stream + template + basic_istream<_CharT, _Traits>& + operator>>(basic_istream<_CharT, _Traits>&& __stream, _Tp& __x) + { + __stream >> __x; + return __stream; + } +#endif // __GXX_EXPERIMENTAL_CXX0X__ + _GLIBCXX_END_NAMESPACE #endif /* _GLIBCXX_IOSFWD */ Index: libstdc++-v3/include/ext/vstring.h =================================================================== --- libstdc++-v3/include/ext/vstring.h (revision 140759) +++ libstdc++-v3/include/ext/vstring.h (working copy) @@ -1342,11 +1342,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) * time. */ void -#ifdef __GXX_EXPERIMENTAL_CXX0X__ - swap(__versa_string&& __s) -#else swap(__versa_string& __s) -#endif { this->_M_swap(__s); } // String operations: Index: libstdc++-v3/include/bits/stl_list.h =================================================================== --- libstdc++-v3/include/bits/stl_list.h (revision 140759) +++ libstdc++-v3/include/bits/stl_list.h (working copy) @@ -1040,11 +1040,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL * function. */ void -#ifdef __GXX_EXPERIMENTAL_CXX0X__ - swap(list&& __x) -#else swap(list& __x) -#endif { _List_node_base::swap(this->_M_impl._M_node, __x._M_impl._M_node); Index: libstdc++-v3/include/bits/stl_map.h =================================================================== --- libstdc++-v3/include/bits/stl_map.h (revision 140759) +++ libstdc++-v3/include/bits/stl_map.h (working copy) @@ -564,11 +564,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL * that std::swap(m1,m2) will feed to this function. */ void -#ifdef __GXX_EXPERIMENTAL_CXX0X__ - swap(map&& __x) -#else swap(map& __x) -#endif { _M_t.swap(__x._M_t); } /** Index: libstdc++-v3/include/bits/stl_set.h =================================================================== --- libstdc++-v3/include/bits/stl_set.h (revision 140759) +++ libstdc++-v3/include/bits/stl_set.h (working copy) @@ -353,11 +353,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL * std::swap(s1,s2) will feed to this function. */ void -#ifdef __GXX_EXPERIMENTAL_CXX0X__ - swap(set&& __x) -#else swap(set& __x) -#endif { _M_t.swap(__x._M_t); } // insert/erase Index: libstdc++-v3/include/bits/stl_multimap.h =================================================================== --- libstdc++-v3/include/bits/stl_multimap.h (revision 140759) +++ libstdc++-v3/include/bits/stl_multimap.h (working copy) @@ -500,11 +500,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL * std::swap(m1,m2) will feed to this function. */ void -#ifdef __GXX_EXPERIMENTAL_CXX0X__ - swap(multimap&& __x) -#else swap(multimap& __x) -#endif { _M_t.swap(__x._M_t); } /** Index: libstdc++-v3/include/bits/stl_pair.h =================================================================== --- libstdc++-v3/include/bits/stl_pair.h (revision 140759) +++ libstdc++-v3/include/bits/stl_pair.h (working copy) @@ -136,7 +136,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) } void - swap(pair&& __p) + swap(pair& __p) { using std::swap; swap(first, __p.first); Index: libstdc++-v3/include/bits/stl_vector.h =================================================================== --- libstdc++-v3/include/bits/stl_vector.h (revision 140759) +++ libstdc++-v3/include/bits/stl_vector.h (working copy) @@ -864,11 +864,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL * std::swap(v1,v2) will feed to this function. */ void -#ifdef __GXX_EXPERIMENTAL_CXX0X__ - swap(vector&& __x) -#else swap(vector& __x) -#endif { std::swap(this->_M_impl._M_start, __x._M_impl._M_start); std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); Index: libstdc++-v3/include/bits/stl_deque.h =================================================================== --- libstdc++-v3/include/bits/stl_deque.h (revision 140759) +++ libstdc++-v3/include/bits/stl_deque.h (working copy) @@ -1346,11 +1346,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL * std::swap(d1,d2) will feed to this function. */ void -#ifdef __GXX_EXPERIMENTAL_CXX0X__ - swap(deque&& __x) -#else swap(deque& __x) -#endif { std::swap(this->_M_impl._M_start, __x._M_impl._M_start); std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); Index: libstdc++-v3/include/bits/stl_multiset.h =================================================================== --- libstdc++-v3/include/bits/stl_multiset.h (revision 140759) +++ libstdc++-v3/include/bits/stl_multiset.h (working copy) @@ -346,11 +346,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GL * std::swap(s1,s2) will feed to this function. */ void -#ifdef __GXX_EXPERIMENTAL_CXX0X__ - swap(multiset&& __x) -#else swap(multiset& __x) -#endif { _M_t.swap(__x._M_t); } // insert/erase Index: libstdc++-v3/include/bits/stl_iterator.h =================================================================== --- libstdc++-v3/include/bits/stl_iterator.h (revision 140759) +++ libstdc++-v3/include/bits/stl_iterator.h (working copy) @@ -902,7 +902,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) reference operator*() const - { return *_M_current; } + { return std::move(*_M_current); } pointer operator->() const Index: libstdc++-v3/include/bits/stl_bvector.h =================================================================== --- libstdc++-v3/include/bits/stl_bvector.h (revision 140759) +++ libstdc++-v3/include/bits/stl_bvector.h (working copy) @@ -726,11 +726,7 @@ template } void -#ifdef __GXX_EXPERIMENTAL_CXX0X__ - swap(vector&& __x) -#else swap(vector& __x) -#endif { std::swap(this->_M_impl._M_start, __x._M_impl._M_start); std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish); Index: libstdc++-v3/include/bits/stl_tree.h =================================================================== --- libstdc++-v3/include/bits/stl_tree.h (revision 140759) +++ libstdc++-v3/include/bits/stl_tree.h (working copy) @@ -646,11 +646,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) { return get_allocator().max_size(); } void -#ifdef __GXX_EXPERIMENTAL_CXX0X__ - swap(_Rb_tree&& __t); -#else swap(_Rb_tree& __t); -#endif // Insert/erase. pair @@ -1075,11 +1071,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) typename _Compare, typename _Alloc> void _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: -#ifdef __GXX_EXPERIMENTAL_CXX0X__ - swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&& __t) -#else swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __t) -#endif { if (_M_root() == 0) { Index: libstdc++-v3/include/bits/stl_move.h =================================================================== --- libstdc++-v3/include/bits/stl_move.h (revision 140759) +++ libstdc++-v3/include/bits/stl_move.h (working copy) @@ -52,13 +52,13 @@ _GLIBCXX_BEGIN_NAMESPACE(std) template inline _Tp&& - forward(typename std::identity<_Tp>::type&& __t) - { return __t; } + forward(typename std::identity<_Tp>::type& __t) + { return static_cast<_Tp&&>(__t); } template inline typename std::remove_reference<_Tp>::type&& move(_Tp&& __t) - { return __t; } + { return static_cast::type&&>(__t); } _GLIBCXX_END_NAMESPACE Index: libstdc++-v3/testsuite/27_io/rvalue_streams.cc =================================================================== --- libstdc++-v3/testsuite/27_io/rvalue_streams.cc (revision 0) +++ libstdc++-v3/testsuite/27_io/rvalue_streams.cc (revision 0) @@ -0,0 +1,40 @@ +// Copyright (C) 2008 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// { dg-do run } + +#include +#include +#include + +void +test01() +{ + int i = 1742; + std::string result = (std::ostringstream() << i).str(); + int i2; + std::istringstream(result) >> i2; + VERIFY (i == i2); +} + +int +main() +{ + test01(); + return 0; +} Index: libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc =================================================================== --- libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc (revision 140759) +++ libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc (working copy) @@ -19,7 +19,7 @@ // USA. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 992 } +// { dg-error "no matching" "" { target *-*-* } 988 } // { dg-excess-errors "" } #include Index: libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc =================================================================== --- libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc (revision 140759) +++ libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc (working copy) @@ -19,7 +19,7 @@ // USA. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1033 } +// { dg-error "no matching" "" { target *-*-* } 1029 } // { dg-excess-errors "" } #include Index: libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc =================================================================== --- libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc (revision 140759) +++ libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc (working copy) @@ -19,7 +19,7 @@ // USA. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 932 } +// { dg-error "no matching" "" { target *-*-* } 928 } // { dg-excess-errors "" } #include Index: libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc =================================================================== --- libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc (revision 140759) +++ libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc (working copy) @@ -19,7 +19,7 @@ // USA. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 932 } +// { dg-error "no matching" "" { target *-*-* } 928 } // { dg-excess-errors "" } #include Index: libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc =================================================================== --- libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc (revision 140759) +++ libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc (working copy) @@ -19,7 +19,7 @@ // USA. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1449 } +// { dg-error "no matching" "" { target *-*-* } 1445 } // { dg-excess-errors "" } #include Index: libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc =================================================================== --- libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc (revision 140759) +++ libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc (working copy) @@ -19,7 +19,7 @@ // USA. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1533 } +// { dg-error "no matching" "" { target *-*-* } 1529 } // { dg-excess-errors "" } #include Index: libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc =================================================================== --- libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc (revision 140759) +++ libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc (working copy) @@ -19,7 +19,7 @@ // USA. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1388 } +// { dg-error "no matching" "" { target *-*-* } 1384 } // { dg-excess-errors "" } #include Index: libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc =================================================================== --- libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc (revision 140759) +++ libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc (working copy) @@ -19,7 +19,7 @@ // USA. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1388 } +// { dg-error "no matching" "" { target *-*-* } 1384 } // { dg-excess-errors "" } #include Index: libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc =================================================================== --- libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc (revision 140759) +++ libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc (working copy) @@ -19,7 +19,7 @@ // USA. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1317 } +// { dg-error "no matching" "" { target *-*-* } 1313 } // { dg-excess-errors "" } #include Index: libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc =================================================================== --- libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc (revision 140759) +++ libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc (working copy) @@ -19,7 +19,7 @@ // USA. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1286 } +// { dg-error "no matching" "" { target *-*-* } 1282 } // { dg-excess-errors "" } #include Index: libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc =================================================================== --- libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc (revision 140759) +++ libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc (working copy) @@ -19,7 +19,7 @@ // USA. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1286 } +// { dg-error "no matching" "" { target *-*-* } 1282 } // { dg-excess-errors "" } #include Index: libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc =================================================================== --- libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc (revision 140759) +++ libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc (working copy) @@ -19,7 +19,7 @@ // USA. // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1286 } +// { dg-error "no matching" "" { target *-*-* } 1282 } // { dg-excess-errors "" } #include