Hi, I'm committing the below from Daniel. Thanks!
Tested x86_64-linux. Paolo. ///////////////////
2011-11-21 Daniel Krugler <daniel.krueg...@googlemail.com> PR libstdc++/51185 * include/std/type_traits (__is_base_to_derived_ref, __is_lvalue_to_rvalue_ref): Fix. * testsuite/20_util/is_constructible/51185.cc: New. * testsuite/20_util/is_constructible/value-2.cc: Extend. * testsuite/20_util/declval/requirements/1_neg.cc: Adjust dg-error line number. * testsuite/20_util/make_signed/requirements/typedefs_neg.cc: Likewise. * testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc Likewise.
Index: include/std/type_traits =================================================================== --- include/std/type_traits (revision 181554) +++ include/std/type_traits (working copy) @@ -745,6 +745,8 @@ // Implementation for non-reference types. To meet the proper // variable definition semantics, we also need to test for // is_destructible in this case. + // This form should be simplified by a single expression: + // ::delete ::new _Tp(declval<_Arg>()), see c++/51222. struct __do_is_direct_constructible_impl { template<typename _Tp, typename _Arg, typename @@ -778,9 +780,12 @@ struct remove_reference; template<typename _From, typename _To, bool - = is_reference<_From>::value> + = __not_<__or_<is_void<_From>, + is_function<_From>>>::value> struct __is_base_to_derived_ref; + // Detect whether we have a downcast situation during + // reference binding. template<typename _From, typename _To> struct __is_base_to_derived_ref<_From, _To, true> { @@ -803,6 +808,8 @@ is_rvalue_reference<_To>>::value> struct __is_lvalue_to_rvalue_ref; + // Detect whether we have an lvalue of non-function type + // bound to a reference-compatible rvalue-reference. template<typename _From, typename _To> struct __is_lvalue_to_rvalue_ref<_From, _To, true> { @@ -810,8 +817,9 @@ _From>::type>::type __src_t; typedef typename remove_cv<typename remove_reference< _To>::type>::type __dst_t; - typedef __or_<is_same<__src_t, __dst_t>, - is_base_of<__dst_t, __src_t>> type; + typedef __and_<__not_<is_function<__src_t>>, + __or_<is_same<__src_t, __dst_t>, + is_base_of<__dst_t, __src_t>>> type; static constexpr bool value = type::value; }; @@ -823,9 +831,9 @@ // Here we handle direct-initialization to a reference type as // equivalent to a static_cast modulo overshooting conversions. // These are restricted to the following conversions: - // a) A glvalue of a base class to a derived class reference + // a) A base class value to a derived class reference // b) An lvalue to an rvalue-reference of reference-compatible - // types + // types that are not functions template<typename _Tp, typename _Arg> struct __is_direct_constructible_ref_cast : public __and_<__is_static_castable<_Arg, _Tp>, @@ -850,7 +858,9 @@ // Since default-construction and binary direct-initialization have // been handled separately, the implementation of the remaining - // n-ary construction cases is rather straightforward. + // n-ary construction cases is rather straightforward. We can use + // here a functional cast, because array types are excluded anyway + // and this form is never interpreted as a C cast. struct __do_is_nary_constructible_impl { template<typename _Tp, typename... _Args, typename Index: testsuite/20_util/make_signed/requirements/typedefs_neg.cc =================================================================== --- testsuite/20_util/make_signed/requirements/typedefs_neg.cc (revision 181554) +++ testsuite/20_util/make_signed/requirements/typedefs_neg.cc (working copy) @@ -48,5 +48,5 @@ // { dg-error "required from here" "" { target *-*-* } 40 } // { dg-error "required from here" "" { target *-*-* } 42 } -// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1545 } -// { dg-error "declaration of" "" { target *-*-* } 1509 } +// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1555 } +// { dg-error "declaration of" "" { target *-*-* } 1519 } Index: testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc =================================================================== --- testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc (revision 181554) +++ testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc (working copy) @@ -48,5 +48,5 @@ // { dg-error "required from here" "" { target *-*-* } 40 } // { dg-error "required from here" "" { target *-*-* } 42 } -// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1463 } -// { dg-error "declaration of" "" { target *-*-* } 1427 } +// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1473 } +// { dg-error "declaration of" "" { target *-*-* } 1437 } Index: testsuite/20_util/declval/requirements/1_neg.cc =================================================================== --- testsuite/20_util/declval/requirements/1_neg.cc (revision 181554) +++ testsuite/20_util/declval/requirements/1_neg.cc (working copy) @@ -19,7 +19,7 @@ // with this library; see the file COPYING3. If not see // <http://www.gnu.org/licenses/>. -// { dg-error "static assertion failed" "" { target *-*-* } 1759 } +// { dg-error "static assertion failed" "" { target *-*-* } 1769 } #include <utility> Index: testsuite/20_util/is_constructible/value-2.cc =================================================================== --- testsuite/20_util/is_constructible/value-2.cc (revision 181554) +++ testsuite/20_util/is_constructible/value-2.cc (working copy) @@ -817,3 +817,5 @@ "Error"); static_assert(!std::is_constructible<int&&, ExplicitTo<double&&>>::value, "Error"); + +static_assert(std::is_constructible<void(&&)(), void(&)()>::value, "Error"); Index: testsuite/20_util/is_constructible/51185.cc =================================================================== --- testsuite/20_util/is_constructible/51185.cc (revision 0) +++ testsuite/20_util/is_constructible/51185.cc (revision 0) @@ -0,0 +1,39 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } + +// Copyright (C) 2011 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 3, 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 COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <type_traits> + +struct A { }; +struct B : A { }; + +// libstdc++/51185 +void f() +{ + static_assert(!std::is_constructible<B &&, A>(), ""); + static_assert(!std::is_constructible<B const &&, A>(), ""); + static_assert(!std::is_constructible<B const &&, A const>(), ""); + static_assert(!std::is_constructible<B volatile &&, A>(), ""); + static_assert(!std::is_constructible<B volatile &&, A volatile>(), ""); + static_assert(!std::is_constructible<B const volatile &&, A>(), ""); + static_assert(!std::is_constructible<B const volatile &&, A const>(), ""); + static_assert(!std::is_constructible<B const volatile &&, A volatile>(), ""); + static_assert(!std::is_constructible<B const volatile &&, + A const volatile>(), ""); +}