This implements Eric Niebler's suggestion of a more lightweight std::declval, which doesn't need to instantiate std::add_rvalue_reference (and its base class and helpers).
PR libstdc++/71187 * include/std/type_traits (__declval): New function to deduce return type of declval. (__declval_protector::_delegate): Remove. (declval): Use __declval instead of add_rvalue_reference and __declval_protector::__delegate. * testsuite/20_util/declval/requirements/1_neg.cc: Adjust dg-error lineno. * testsuite/20_util/make_signed/requirements/typedefs_neg.cc: Likewise. * testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc: Likewise. Tested powerpc64le-linux, committed to trunk.
commit 05558f97c64247cf421eff8b17570a0844794cbc Author: Jonathan Wakely <jwak...@redhat.com> Date: Fri Sep 15 14:49:08 2017 +0100 PR libstdc++/71187 reimplement declval without add_rvalue_reference PR libstdc++/71187 * include/std/type_traits (__declval): New function to deduce return type of declval. (__declval_protector::_delegate): Remove. (declval): Use __declval instead of add_rvalue_reference and __declval_protector::__delegate. * testsuite/20_util/declval/requirements/1_neg.cc: Adjust dg-error lineno. * testsuite/20_util/make_signed/requirements/typedefs_neg.cc: Likewise. * testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc: Likewise. diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits index f021c42396c..15b0d92bcb6 100644 --- a/libstdc++-v3/include/std/type_traits +++ b/libstdc++-v3/include/std/type_traits @@ -754,15 +754,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Destructible and constructible type properties. - template<typename> - struct add_rvalue_reference; - /** * @brief Utility to simplify expressions used in unevaluated operands * @ingroup utilities */ + + template<typename _Tp, typename _Up = _Tp&&> + _Up + __declval(int); + template<typename _Tp> - typename add_rvalue_reference<_Tp>::type declval() noexcept; + _Tp + __declval(long); + + template<typename _Tp> + auto declval() noexcept -> decltype(__declval<_Tp>(0)); template<typename, unsigned = 0> struct extent; @@ -2079,16 +2085,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __declval_protector { static const bool __stop = false; - static typename add_rvalue_reference<_Tp>::type __delegate(); }; template<typename _Tp> - inline typename add_rvalue_reference<_Tp>::type - declval() noexcept + auto declval() noexcept -> decltype(__declval<_Tp>(0)) { static_assert(__declval_protector<_Tp>::__stop, "declval() must not be used!"); - return __declval_protector<_Tp>::__delegate(); + return __declval<_Tp>(0); } /// result_of 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 4e254e89191..17b41a007db 100644 --- a/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc +++ b/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc @@ -18,7 +18,7 @@ // with this library; see the file COPYING3. If not see // <http://www.gnu.org/licenses/>. -// { dg-error "static assertion failed" "" { target *-*-* } 2089 } +// { dg-error "static assertion failed" "" { target *-*-* } 2093 } #include <utility> 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 e3e80f91979..308155383f0 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 @@ -47,4 +47,4 @@ void test01() // { dg-error "required from here" "" { target *-*-* } 39 } // { dg-error "required from here" "" { target *-*-* } 41 } -// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1754 } +// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1760 } 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 86b0c2d6da7..412608e5669 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 @@ -47,5 +47,5 @@ void test01() // { dg-error "required from here" "" { target *-*-* } 39 } // { dg-error "required from here" "" { target *-*-* } 41 } -// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1650 } +// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1656 }