diff options
author | redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4> | 2017-12-14 17:18:22 +0000 |
---|---|---|
committer | redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4> | 2017-12-14 17:18:22 +0000 |
commit | f07a7cbfc92ff5401a296d4661f4555139ed8eb8 (patch) | |
tree | 92c8339eeda08ec4c2912c57f9aeb729e4d729e7 | |
parent | 824a2485e2c232a2416eb850aabce3c1028e05fc (diff) | |
download | gcc-f07a7cbfc92ff5401a296d4661f4555139ed8eb8.tar.gz |
PR libstdc++/83427 detect weak result type from noexcept functions
PR libstdc++/83427
* include/bits/refwrap.h (_Maybe_unary_or_binary_function): Move here
from <bits/std_function.h>.
(_Mem_fn_traits_base, _Mem_fn_traits): Move here, from <functional>.
(_Weak_result_type_impl, _Reference_wrapper_base): Deduce noexcept
for function types. Remove partial specializations for member
functions.
(_Weak_result_type_impl): Remove unused partial specializations for
non-referenceable function types and for references to functions.
(_Weak_result_type_memfun, _Reference_wrapper_base_memfun): New
helpers to handle member functions via _Mem_fn_traits.
(_Weak_result_type, reference_wrapper): Derive from new helpers.
* include/bits/std_function.h (_Maybe_unary_or_binary_function): Move
to <bits/refwrap.h>.
* include/std/functional (_Pack, _AllConvertible, _NotSame): Remove.
(_Mem_fn_traits_base, _Mem_fn_traits): Move to <bits/refwrap.h>.
* testsuite/20_util/bind/83427.cc: New test.
* testsuite/20_util/bind/refqual.cc: Add noexcept to functions and
check for weak result types.
* testsuite/20_util/reference_wrapper/83427.cc: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@255651 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | libstdc++-v3/ChangeLog | 21 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/refwrap.h | 242 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/std_function.h | 19 | ||||
-rw-r--r-- | libstdc++-v3/include/std/functional | 65 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/bind/83427.cc | 31 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/bind/refqual.cc | 8 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/reference_wrapper/83427.cc | 39 |
7 files changed, 209 insertions, 216 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index e035302bed4..143739f1ce2 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,26 @@ 2017-12-14 Jonathan Wakely <jwakely@redhat.com> + PR libstdc++/83427 + * include/bits/refwrap.h (_Maybe_unary_or_binary_function): Move here + from <bits/std_function.h>. + (_Mem_fn_traits_base, _Mem_fn_traits): Move here, from <functional>. + (_Weak_result_type_impl, _Reference_wrapper_base): Deduce noexcept + for function types. Remove partial specializations for member + functions. + (_Weak_result_type_impl): Remove unused partial specializations for + non-referenceable function types and for references to functions. + (_Weak_result_type_memfun, _Reference_wrapper_base_memfun): New + helpers to handle member functions via _Mem_fn_traits. + (_Weak_result_type, reference_wrapper): Derive from new helpers. + * include/bits/std_function.h (_Maybe_unary_or_binary_function): Move + to <bits/refwrap.h>. + * include/std/functional (_Pack, _AllConvertible, _NotSame): Remove. + (_Mem_fn_traits_base, _Mem_fn_traits): Move to <bits/refwrap.h>. + * testsuite/20_util/bind/83427.cc: New test. + * testsuite/20_util/bind/refqual.cc: Add noexcept to functions and + check for weak result types. + * testsuite/20_util/reference_wrapper/83427.cc: New test. + * testsuite/26_numerics/complex/inserters_extractors/char/dr2714.cc: Add tests using noskipws. diff --git a/libstdc++-v3/include/bits/refwrap.h b/libstdc++-v3/include/bits/refwrap.h index 5e5b61060e3..1b64cd8fbf5 100644 --- a/libstdc++-v3/include/bits/refwrap.h +++ b/libstdc++-v3/include/bits/refwrap.h @@ -44,6 +44,69 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION + /** + * Derives from @c unary_function or @c binary_function, or perhaps + * nothing, depending on the number of arguments provided. The + * primary template is the basis case, which derives nothing. + */ + template<typename _Res, typename... _ArgTypes> + struct _Maybe_unary_or_binary_function { }; + + /// Derives from @c unary_function, as appropriate. + template<typename _Res, typename _T1> + struct _Maybe_unary_or_binary_function<_Res, _T1> + : std::unary_function<_T1, _Res> { }; + + /// Derives from @c binary_function, as appropriate. + template<typename _Res, typename _T1, typename _T2> + struct _Maybe_unary_or_binary_function<_Res, _T1, _T2> + : std::binary_function<_T1, _T2, _Res> { }; + + template<typename _Signature> + struct _Mem_fn_traits; + + template<typename _Res, typename _Class, typename... _ArgTypes> + struct _Mem_fn_traits_base + { + using __result_type = _Res; + using __maybe_type + = _Maybe_unary_or_binary_function<_Res, _Class*, _ArgTypes...>; + using __arity = integral_constant<size_t, sizeof...(_ArgTypes)>; + }; + +#define _GLIBCXX_MEM_FN_TRAITS2(_CV, _REF, _LVAL, _RVAL) \ + template<typename _Res, typename _Class, typename... _ArgTypes> \ + struct _Mem_fn_traits<_Res (_Class::*)(_ArgTypes...) _CV _REF> \ + : _Mem_fn_traits_base<_Res, _CV _Class, _ArgTypes...> \ + { \ + using __vararg = false_type; \ + }; \ + template<typename _Res, typename _Class, typename... _ArgTypes> \ + struct _Mem_fn_traits<_Res (_Class::*)(_ArgTypes... ...) _CV _REF> \ + : _Mem_fn_traits_base<_Res, _CV _Class, _ArgTypes...> \ + { \ + using __vararg = true_type; \ + }; + +#define _GLIBCXX_MEM_FN_TRAITS(_REF, _LVAL, _RVAL) \ + _GLIBCXX_MEM_FN_TRAITS2( , _REF, _LVAL, _RVAL) \ + _GLIBCXX_MEM_FN_TRAITS2(const , _REF, _LVAL, _RVAL) \ + _GLIBCXX_MEM_FN_TRAITS2(volatile , _REF, _LVAL, _RVAL) \ + _GLIBCXX_MEM_FN_TRAITS2(const volatile, _REF, _LVAL, _RVAL) + +_GLIBCXX_MEM_FN_TRAITS( , true_type, true_type) +_GLIBCXX_MEM_FN_TRAITS(&, true_type, false_type) +_GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) + +#if __cplusplus > 201402L +_GLIBCXX_MEM_FN_TRAITS(noexcept, true_type, true_type) +_GLIBCXX_MEM_FN_TRAITS(& noexcept, true_type, false_type) +_GLIBCXX_MEM_FN_TRAITS(&& noexcept, false_type, true_type) +#endif + +#undef _GLIBCXX_MEM_FN_TRAITS +#undef _GLIBCXX_MEM_FN_TRAITS2 + /// If we have found a result_type, extract it. template<typename _Functor, typename = __void_t<>> struct _Maybe_get_result_type @@ -64,101 +127,52 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { }; /// Retrieve the result type for a function type. - template<typename _Res, typename... _ArgTypes> - struct _Weak_result_type_impl<_Res(_ArgTypes...)> - { typedef _Res result_type; }; - - template<typename _Res, typename... _ArgTypes> - struct _Weak_result_type_impl<_Res(_ArgTypes......)> - { typedef _Res result_type; }; - - template<typename _Res, typename... _ArgTypes> - struct _Weak_result_type_impl<_Res(_ArgTypes...) const> + template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM> + struct _Weak_result_type_impl<_Res(_ArgTypes...) _GLIBCXX_NOEXCEPT_QUAL> { typedef _Res result_type; }; - template<typename _Res, typename... _ArgTypes> - struct _Weak_result_type_impl<_Res(_ArgTypes......) const> - { typedef _Res result_type; }; - - template<typename _Res, typename... _ArgTypes> - struct _Weak_result_type_impl<_Res(_ArgTypes...) volatile> - { typedef _Res result_type; }; - - template<typename _Res, typename... _ArgTypes> - struct _Weak_result_type_impl<_Res(_ArgTypes......) volatile> - { typedef _Res result_type; }; - - template<typename _Res, typename... _ArgTypes> - struct _Weak_result_type_impl<_Res(_ArgTypes...) const volatile> - { typedef _Res result_type; }; - - template<typename _Res, typename... _ArgTypes> - struct _Weak_result_type_impl<_Res(_ArgTypes......) const volatile> - { typedef _Res result_type; }; - - /// Retrieve the result type for a function reference. - template<typename _Res, typename... _ArgTypes> - struct _Weak_result_type_impl<_Res(&)(_ArgTypes...)> - { typedef _Res result_type; }; - - template<typename _Res, typename... _ArgTypes> - struct _Weak_result_type_impl<_Res(&)(_ArgTypes......)> + /// Retrieve the result type for a varargs function type. + template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM> + struct _Weak_result_type_impl<_Res(_ArgTypes......) _GLIBCXX_NOEXCEPT_QUAL> { typedef _Res result_type; }; /// Retrieve the result type for a function pointer. - template<typename _Res, typename... _ArgTypes> - struct _Weak_result_type_impl<_Res(*)(_ArgTypes...)> - { typedef _Res result_type; }; - - template<typename _Res, typename... _ArgTypes> - struct _Weak_result_type_impl<_Res(*)(_ArgTypes......)> + template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM> + struct _Weak_result_type_impl<_Res(*)(_ArgTypes...) _GLIBCXX_NOEXCEPT_QUAL> { typedef _Res result_type; }; - /// Retrieve result type for a member function pointer. - template<typename _Res, typename _Class, typename... _ArgTypes> - struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...)> + /// Retrieve the result type for a varargs function pointer. + template<typename _Res, typename... _ArgTypes _GLIBCXX_NOEXCEPT_PARM> + struct + _Weak_result_type_impl<_Res(*)(_ArgTypes......) _GLIBCXX_NOEXCEPT_QUAL> { typedef _Res result_type; }; - template<typename _Res, typename _Class, typename... _ArgTypes> - struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes......)> - { typedef _Res result_type; }; - - /// Retrieve result type for a const member function pointer. - template<typename _Res, typename _Class, typename... _ArgTypes> - struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...) const> - { typedef _Res result_type; }; - - template<typename _Res, typename _Class, typename... _ArgTypes> - struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes......) const> - { typedef _Res result_type; }; - - /// Retrieve result type for a volatile member function pointer. - template<typename _Res, typename _Class, typename... _ArgTypes> - struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...) volatile> - { typedef _Res result_type; }; - - template<typename _Res, typename _Class, typename... _ArgTypes> - struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes......) volatile> - { typedef _Res result_type; }; + // Let _Weak_result_type_impl perform the real work. + template<typename _Functor, + bool = is_member_function_pointer<_Functor>::value> + struct _Weak_result_type_memfun + : _Weak_result_type_impl<_Functor> + { }; - /// Retrieve result type for a const volatile member function pointer. - template<typename _Res, typename _Class, typename... _ArgTypes> - struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...) - const volatile> - { typedef _Res result_type; }; + // A pointer to member function has a weak result type. + template<typename _MemFunPtr> + struct _Weak_result_type_memfun<_MemFunPtr, true> + { + using result_type = typename _Mem_fn_traits<_MemFunPtr>::__result_type; + }; - template<typename _Res, typename _Class, typename... _ArgTypes> - struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes......) - const volatile> - { typedef _Res result_type; }; + // A pointer to data member doesn't have a weak result type. + template<typename _Func, typename _Class> + struct _Weak_result_type_memfun<_Func _Class::*, false> + { }; /** * Strip top-level cv-qualifiers from the function object and let - * _Weak_result_type_impl perform the real work. + * _Weak_result_type_memfun perform the real work. */ template<typename _Functor> struct _Weak_result_type - : _Weak_result_type_impl<typename remove_cv<_Functor>::type> + : _Weak_result_type_memfun<typename remove_cv<_Functor>::type> { }; // Detect nested argument_type. @@ -201,8 +215,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { }; // - a function type (unary) - template<typename _Res, typename _T1> - struct _Reference_wrapper_base<_Res(_T1)> + template<typename _Res, typename _T1 _GLIBCXX_NOEXCEPT_PARM> + struct _Reference_wrapper_base<_Res(_T1) _GLIBCXX_NOEXCEPT_QUAL> : unary_function<_T1, _Res> { }; @@ -222,8 +236,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { }; // - a function type (binary) - template<typename _Res, typename _T1, typename _T2> - struct _Reference_wrapper_base<_Res(_T1, _T2)> + template<typename _Res, typename _T1, typename _T2 _GLIBCXX_NOEXCEPT_PARM> + struct _Reference_wrapper_base<_Res(_T1, _T2) _GLIBCXX_NOEXCEPT_QUAL> : binary_function<_T1, _T2, _Res> { }; @@ -243,64 +257,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { }; // - a function pointer type (unary) - template<typename _Res, typename _T1> - struct _Reference_wrapper_base<_Res(*)(_T1)> + template<typename _Res, typename _T1 _GLIBCXX_NOEXCEPT_PARM> + struct _Reference_wrapper_base<_Res(*)(_T1) _GLIBCXX_NOEXCEPT_QUAL> : unary_function<_T1, _Res> { }; // - a function pointer type (binary) - template<typename _Res, typename _T1, typename _T2> - struct _Reference_wrapper_base<_Res(*)(_T1, _T2)> + template<typename _Res, typename _T1, typename _T2 _GLIBCXX_NOEXCEPT_PARM> + struct _Reference_wrapper_base<_Res(*)(_T1, _T2) _GLIBCXX_NOEXCEPT_QUAL> : binary_function<_T1, _T2, _Res> { }; - // - a pointer to member function type (unary, no qualifiers) - template<typename _Res, typename _T1> - struct _Reference_wrapper_base<_Res (_T1::*)()> - : unary_function<_T1*, _Res> - { }; - - // - a pointer to member function type (binary, no qualifiers) - template<typename _Res, typename _T1, typename _T2> - struct _Reference_wrapper_base<_Res (_T1::*)(_T2)> - : binary_function<_T1*, _T2, _Res> - { }; - - // - a pointer to member function type (unary, const) - template<typename _Res, typename _T1> - struct _Reference_wrapper_base<_Res (_T1::*)() const> - : unary_function<const _T1*, _Res> - { }; - - // - a pointer to member function type (binary, const) - template<typename _Res, typename _T1, typename _T2> - struct _Reference_wrapper_base<_Res (_T1::*)(_T2) const> - : binary_function<const _T1*, _T2, _Res> - { }; - - // - a pointer to member function type (unary, volatile) - template<typename _Res, typename _T1> - struct _Reference_wrapper_base<_Res (_T1::*)() volatile> - : unary_function<volatile _T1*, _Res> - { }; - - // - a pointer to member function type (binary, volatile) - template<typename _Res, typename _T1, typename _T2> - struct _Reference_wrapper_base<_Res (_T1::*)(_T2) volatile> - : binary_function<volatile _T1*, _T2, _Res> - { }; - - // - a pointer to member function type (unary, const volatile) - template<typename _Res, typename _T1> - struct _Reference_wrapper_base<_Res (_T1::*)() const volatile> - : unary_function<const volatile _T1*, _Res> + template<typename _Tp, bool = is_member_function_pointer<_Tp>::value> + struct _Reference_wrapper_base_memfun + : _Reference_wrapper_base<_Tp> { }; - // - a pointer to member function type (binary, const volatile) - template<typename _Res, typename _T1, typename _T2> - struct _Reference_wrapper_base<_Res (_T1::*)(_T2) const volatile> - : binary_function<const volatile _T1*, _T2, _Res> - { }; + template<typename _MemFunPtr> + struct _Reference_wrapper_base_memfun<_MemFunPtr, true> + : _Mem_fn_traits<_MemFunPtr>::__maybe_type + { + using result_type = typename _Mem_fn_traits<_MemFunPtr>::__result_type; + }; /** * @brief Primary class template for reference_wrapper. @@ -309,7 +287,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION */ template<typename _Tp> class reference_wrapper - : public _Reference_wrapper_base<typename remove_cv<_Tp>::type> + : public _Reference_wrapper_base_memfun<typename remove_cv<_Tp>::type> { _Tp* _M_data; diff --git a/libstdc++-v3/include/bits/std_function.h b/libstdc++-v3/include/bits/std_function.h index a9ba7567b33..94b7ee99067 100644 --- a/libstdc++-v3/include/bits/std_function.h +++ b/libstdc++-v3/include/bits/std_function.h @@ -49,25 +49,6 @@ namespace std _GLIBCXX_VISIBILITY(default) _GLIBCXX_BEGIN_NAMESPACE_VERSION /** - * Derives from @c unary_function or @c binary_function, or perhaps - * nothing, depending on the number of arguments provided. The - * primary template is the basis case, which derives nothing. - */ - template<typename _Res, typename... _ArgTypes> - struct _Maybe_unary_or_binary_function { }; - - /// Derives from @c unary_function, as appropriate. - template<typename _Res, typename _T1> - struct _Maybe_unary_or_binary_function<_Res, _T1> - : std::unary_function<_T1, _Res> { }; - - /// Derives from @c binary_function, as appropriate. - template<typename _Res, typename _T1, typename _T2> - struct _Maybe_unary_or_binary_function<_Res, _T1, _T2> - : std::binary_function<_T1, _T2, _Res> { }; - - - /** * @brief Exception class thrown when class template function's * operator() is called with an empty target. * @ingroup exceptions diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional index a6d121bb150..f94c63b213e 100644 --- a/libstdc++-v3/include/std/functional +++ b/libstdc++-v3/include/std/functional @@ -55,7 +55,8 @@ #include <type_traits> #include <bits/functional_hash.h> #include <bits/invoke.h> -#include <bits/std_function.h> +#include <bits/refwrap.h> // std::reference_wrapper and _Mem_fn_traits +#include <bits/std_function.h> // std::function #if __cplusplus > 201402L # include <unordered_map> # include <vector> @@ -82,68 +83,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } #endif - template<typename... _Types> - struct _Pack : integral_constant<size_t, sizeof...(_Types)> - { }; - - template<typename _From, typename _To, bool = _From::value == _To::value> - struct _AllConvertible : false_type - { }; - - template<typename... _From, typename... _To> - struct _AllConvertible<_Pack<_From...>, _Pack<_To...>, true> - : __and_<is_convertible<_From, _To>...> - { }; - - template<typename _Tp1, typename _Tp2> - using _NotSame = __not_<is_same<typename std::decay<_Tp1>::type, - typename std::decay<_Tp2>::type>>; - - template<typename _Signature> - struct _Mem_fn_traits; - - template<typename _Res, typename _Class, typename... _ArgTypes> - struct _Mem_fn_traits_base - { - using __result_type = _Res; - using __maybe_type - = _Maybe_unary_or_binary_function<_Res, _Class*, _ArgTypes...>; - using __arity = integral_constant<size_t, sizeof...(_ArgTypes)>; - }; - -#define _GLIBCXX_MEM_FN_TRAITS2(_CV, _REF, _LVAL, _RVAL) \ - template<typename _Res, typename _Class, typename... _ArgTypes> \ - struct _Mem_fn_traits<_Res (_Class::*)(_ArgTypes...) _CV _REF> \ - : _Mem_fn_traits_base<_Res, _CV _Class, _ArgTypes...> \ - { \ - using __vararg = false_type; \ - }; \ - template<typename _Res, typename _Class, typename... _ArgTypes> \ - struct _Mem_fn_traits<_Res (_Class::*)(_ArgTypes... ...) _CV _REF> \ - : _Mem_fn_traits_base<_Res, _CV _Class, _ArgTypes...> \ - { \ - using __vararg = true_type; \ - }; - -#define _GLIBCXX_MEM_FN_TRAITS(_REF, _LVAL, _RVAL) \ - _GLIBCXX_MEM_FN_TRAITS2( , _REF, _LVAL, _RVAL) \ - _GLIBCXX_MEM_FN_TRAITS2(const , _REF, _LVAL, _RVAL) \ - _GLIBCXX_MEM_FN_TRAITS2(volatile , _REF, _LVAL, _RVAL) \ - _GLIBCXX_MEM_FN_TRAITS2(const volatile, _REF, _LVAL, _RVAL) - -_GLIBCXX_MEM_FN_TRAITS( , true_type, true_type) -_GLIBCXX_MEM_FN_TRAITS(&, true_type, false_type) -_GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type) - -#if __cplusplus > 201402L -_GLIBCXX_MEM_FN_TRAITS(noexcept, true_type, true_type) -_GLIBCXX_MEM_FN_TRAITS(& noexcept, true_type, false_type) -_GLIBCXX_MEM_FN_TRAITS(&& noexcept, false_type, true_type) -#endif - -#undef _GLIBCXX_MEM_FN_TRAITS -#undef _GLIBCXX_MEM_FN_TRAITS2 - template<typename _MemFunPtr, bool __is_mem_fn = is_member_function_pointer<_MemFunPtr>::value> class _Mem_fn_base diff --git a/libstdc++-v3/testsuite/20_util/bind/83427.cc b/libstdc++-v3/testsuite/20_util/bind/83427.cc new file mode 100644 index 00000000000..e96841435f2 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/bind/83427.cc @@ -0,0 +1,31 @@ +// Copyright (C) 2017 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/>. + +// { dg-options "-std=gnu++17" } +// { dg-do compile { target c++17 } } + +#include <functional> + +// PR libstdc++/83427 + +int f() noexcept { return 0; } +auto b = std::bind(f); +static_assert(std::is_same_v<decltype(b)::result_type, int>); + +struct X { long f() const & noexcept { return 0L; } }; +auto b2 = std::bind(&X::f, X{}); +static_assert(std::is_same_v<decltype(b2)::result_type, long>); diff --git a/libstdc++-v3/testsuite/20_util/bind/refqual.cc b/libstdc++-v3/testsuite/20_util/bind/refqual.cc index e7088746607..09fe6d52d37 100644 --- a/libstdc++-v3/testsuite/20_util/bind/refqual.cc +++ b/libstdc++-v3/testsuite/20_util/bind/refqual.cc @@ -22,8 +22,8 @@ struct X { - int f() const& { return 0; } - int g(int i, ...)& { return i; } + int f() const& noexcept { return 0; } + int g(int i, ...)& noexcept { return i; } }; void @@ -34,6 +34,10 @@ test01() VERIFY( b() == 0 ); auto bb = std::bind(&X::g, &x, 1, 2); VERIFY( bb() == 1 ); + + // Check for weak result types: + using T1 = decltype(b)::result_type; + using T2 = decltype(bb)::result_type; } int diff --git a/libstdc++-v3/testsuite/20_util/reference_wrapper/83427.cc b/libstdc++-v3/testsuite/20_util/reference_wrapper/83427.cc new file mode 100644 index 00000000000..c4b360f0bb8 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/reference_wrapper/83427.cc @@ -0,0 +1,39 @@ +// Copyright (C) 2017 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/>. + +// { dg-options "-std=gnu++17" } +// { dg-do compile { target c++17 } } + +#include <functional> + +// PR libstdc++/83427 + +int f(short) noexcept { return 0; } +std::reference_wrapper<decltype(f)> r(f); +static_assert(std::is_same_v<decltype(r)::result_type, int>); +static_assert(std::is_same_v<decltype(r)::argument_type, short>); + +auto* p = &f; +std::reference_wrapper<decltype(&f)> r2(p); +static_assert(std::is_same_v<decltype(r2)::result_type, int>); +static_assert(std::is_same_v<decltype(r2)::argument_type, short>); + +struct X { long f() const & noexcept { return 0L; } }; +auto m = &X::f; +std::reference_wrapper<decltype(m)> r3(m); +static_assert(std::is_same_v<decltype(r3)::result_type, long>); +static_assert(std::is_same_v<decltype(r3)::argument_type, const X*>); |