summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>2017-12-14 17:29:22 +0000
committerredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>2017-12-14 17:29:22 +0000
commit0e2e7e374ff8b9c14ffabb187b35eaddf61d5da5 (patch)
treed47a7880814f345585a7aa7d61d1b5702893304e
parent038cd0e355f06b91eb170524e8acea674edaaa16 (diff)
downloadgcc-0e2e7e374ff8b9c14ffabb187b35eaddf61d5da5.tar.gz
PR libstdc++/83427 detect weak result type from noexcept functions
PR libstdc++/83427 * include/bits/refwrap.h (_Weak_result_type_impl) (_Reference_wrapper_base): Deduce noexcept for function types. * testsuite/20_util/bind/83427.cc: New test. * testsuite/20_util/reference_wrapper/83427.cc: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-7-branch@255652 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--libstdc++-v3/ChangeLog6
-rw-r--r--libstdc++-v3/include/bits/refwrap.h111
-rw-r--r--libstdc++-v3/testsuite/20_util/bind/83427.cc31
-rw-r--r--libstdc++-v3/testsuite/20_util/reference_wrapper/83427.cc39
4 files changed, 139 insertions, 48 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 074c93c647b..5fbf3d67b42 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,11 @@
2017-12-14 Jonathan Wakely <jwakely@redhat.com>
+ PR libstdc++/83427
+ * include/bits/refwrap.h (_Weak_result_type_impl)
+ (_Reference_wrapper_base): Deduce noexcept for function types.
+ * testsuite/20_util/bind/83427.cc: New test.
+ * testsuite/20_util/reference_wrapper/83427.cc: New test.
+
PR libstdc++/59568
* include/std/complex (operator>>): Only use putback if a character
was successfully extracted and only set the value if a number was
diff --git a/libstdc++-v3/include/bits/refwrap.h b/libstdc++-v3/include/bits/refwrap.h
index 124ee97bd2a..86260dac993 100644
--- a/libstdc++-v3/include/bits/refwrap.h
+++ b/libstdc++-v3/include/bits/refwrap.h
@@ -64,12 +64,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ };
/// Retrieve the result type for a function 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; };
- 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; };
template<typename _Res, typename... _ArgTypes>
@@ -106,50 +106,65 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ typedef _Res result_type; };
/// Retrieve the result type for a function pointer.
- 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; };
- 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...)>
+ template<typename _Res, typename _Class, typename... _ArgTypes
+ _GLIBCXX_NOEXCEPT_PARM>
+ struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...)
+ _GLIBCXX_NOEXCEPT_QUAL>
{ typedef _Res result_type; };
- template<typename _Res, typename _Class, typename... _ArgTypes>
- struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes......)>
+ template<typename _Res, typename _Class, typename... _ArgTypes
+ _GLIBCXX_NOEXCEPT_PARM>
+ struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes......)
+ _GLIBCXX_NOEXCEPT_QUAL>
{ 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>
+ template<typename _Res, typename _Class, typename... _ArgTypes
+ _GLIBCXX_NOEXCEPT_PARM>
+ struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...) const
+ _GLIBCXX_NOEXCEPT_QUAL>
{ typedef _Res result_type; };
- template<typename _Res, typename _Class, typename... _ArgTypes>
- struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes......) const>
+ template<typename _Res, typename _Class, typename... _ArgTypes
+ _GLIBCXX_NOEXCEPT_PARM>
+ struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes......) const
+ _GLIBCXX_NOEXCEPT_QUAL>
{ 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>
+ template<typename _Res, typename _Class, typename... _ArgTypes
+ _GLIBCXX_NOEXCEPT_PARM>
+ struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...) volatile
+ _GLIBCXX_NOEXCEPT_QUAL>
{ typedef _Res result_type; };
- template<typename _Res, typename _Class, typename... _ArgTypes>
- struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes......) volatile>
+ template<typename _Res, typename _Class, typename... _ArgTypes
+ _GLIBCXX_NOEXCEPT_PARM>
+ struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes......) volatile
+ _GLIBCXX_NOEXCEPT_QUAL>
{ typedef _Res result_type; };
/// Retrieve result type for a const volatile member function pointer.
- template<typename _Res, typename _Class, typename... _ArgTypes>
+ template<typename _Res, typename _Class, typename... _ArgTypes
+ _GLIBCXX_NOEXCEPT_PARM>
struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...)
- const volatile>
+ const volatile _GLIBCXX_NOEXCEPT_QUAL>
{ typedef _Res result_type; };
- template<typename _Res, typename _Class, typename... _ArgTypes>
+ template<typename _Res, typename _Class, typename... _ArgTypes
+ _GLIBCXX_NOEXCEPT_PARM>
struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes......)
- const volatile>
+ const volatile _GLIBCXX_NOEXCEPT_QUAL>
{ typedef _Res result_type; };
/**
@@ -201,8 +216,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 +237,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,62 +258,62 @@ _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::*)()>
+ template<typename _Res, typename _T1 _GLIBCXX_NOEXCEPT_PARM>
+ struct _Reference_wrapper_base<_Res (_T1::*)() _GLIBCXX_NOEXCEPT_QUAL>
: 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)>
+ 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, const)
- template<typename _Res, typename _T1>
- struct _Reference_wrapper_base<_Res (_T1::*)() const>
+ template<typename _Res, typename _T1 _GLIBCXX_NOEXCEPT_PARM>
+ struct _Reference_wrapper_base<_Res (_T1::*)() const _GLIBCXX_NOEXCEPT_QUAL>
: 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>
+ template<typename _Res, typename _T1, typename _T2 _GLIBCXX_NOEXCEPT_PARM>
+ struct _Reference_wrapper_base<_Res (_T1::*)(_T2) const _GLIBCXX_NOEXCEPT_QUAL>
: 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>
+ template<typename _Res, typename _T1 _GLIBCXX_NOEXCEPT_PARM>
+ struct _Reference_wrapper_base<_Res (_T1::*)() volatile _GLIBCXX_NOEXCEPT_QUAL>
: 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>
+ template<typename _Res, typename _T1, typename _T2 _GLIBCXX_NOEXCEPT_PARM>
+ struct _Reference_wrapper_base<_Res (_T1::*)(_T2) volatile _GLIBCXX_NOEXCEPT_QUAL>
: 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>
+ template<typename _Res, typename _T1 _GLIBCXX_NOEXCEPT_PARM>
+ struct _Reference_wrapper_base<_Res (_T1::*)() const volatile _GLIBCXX_NOEXCEPT_QUAL>
: unary_function<const volatile _T1*, _Res>
{ };
// - 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>
+ template<typename _Res, typename _T1, typename _T2 _GLIBCXX_NOEXCEPT_PARM>
+ struct _Reference_wrapper_base<_Res (_T1::*)(_T2) const volatile _GLIBCXX_NOEXCEPT_QUAL>
: binary_function<const volatile _T1*, _T2, _Res>
{ };
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..3b8a6506966
--- /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++1z } }
+
+#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/reference_wrapper/83427.cc b/libstdc++-v3/testsuite/20_util/reference_wrapper/83427.cc
new file mode 100644
index 00000000000..170caf92045
--- /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++1z } }
+
+#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*>);