From 5db25ab107e93e63ab6a0cb8e8f376c234118d1e Mon Sep 17 00:00:00 2001 From: Daniel Krugler <daniel.kruegler@googlemail.com> Date: Mon, 21 Nov 2011 11:21:13 +0000 Subject: [PATCH] re PR libstdc++/51185 ([C++0x] false-positive results of std::is_constructible) 2011-11-21 Daniel Krugler <daniel.kruegler@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. From-SVN: r181557 --- libstdc++-v3/ChangeLog | 8 ++++ libstdc++-v3/include/std/type_traits | 22 ++++++++--- .../20_util/declval/requirements/1_neg.cc | 2 +- .../20_util/is_constructible/51185.cc | 39 +++++++++++++++++++ .../20_util/is_constructible/value-2.cc | 2 + .../make_signed/requirements/typedefs_neg.cc | 4 +- .../requirements/typedefs_neg.cc | 4 +- 7 files changed, 70 insertions(+), 11 deletions(-) create mode 100644 libstdc++-v3/testsuite/20_util/is_constructible/51185.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 9689052ab664..81a4ac8c9471 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,11 @@ +2011-11-21 Daniel Krugler <daniel.kruegler@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. + 2011-11-21 Paolo Carlini <paolo.carlini@oracle.com> * include/std/tuple (__conv_types, __one_by_one_convertible, diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits index a0208590bb56..46e3f800caba 100644 --- a/libstdc++-v3/include/std/type_traits +++ b/libstdc++-v3/include/std/type_traits @@ -745,6 +745,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // 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 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION 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 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION 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 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _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 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // 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 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // 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 diff --git a/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc b/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc index 1f4065b92a85..33ab45b4bbcb 100644 --- a/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc +++ b/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc @@ -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> diff --git a/libstdc++-v3/testsuite/20_util/is_constructible/51185.cc b/libstdc++-v3/testsuite/20_util/is_constructible/51185.cc new file mode 100644 index 000000000000..faf3969fe83d --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/is_constructible/51185.cc @@ -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>(), ""); +} diff --git a/libstdc++-v3/testsuite/20_util/is_constructible/value-2.cc b/libstdc++-v3/testsuite/20_util/is_constructible/value-2.cc index 24fde9389887..06895e32bb0a 100644 --- a/libstdc++-v3/testsuite/20_util/is_constructible/value-2.cc +++ b/libstdc++-v3/testsuite/20_util/is_constructible/value-2.cc @@ -817,3 +817,5 @@ static_assert(!std::is_constructible<const int&, ExplicitTo<double&&>>::value, "Error"); static_assert(!std::is_constructible<int&&, ExplicitTo<double&&>>::value, "Error"); + +static_assert(std::is_constructible<void(&&)(), void(&)()>::value, "Error"); diff --git a/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc b/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc index d61daf358532..b8bd23f841f4 100644 --- a/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc +++ b/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc @@ -48,5 +48,5 @@ void test01() // { 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 } diff --git a/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc b/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc index ee74be9f267f..96940119ed90 100644 --- a/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc +++ b/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc @@ -48,5 +48,5 @@ void test01() // { 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 } -- GitLab