summaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>2016-01-12 14:54:33 +0000
committerredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>2016-01-12 14:54:33 +0000
commitcbe41f67e27bad79b83b239b9ed447ec64fcadce (patch)
treec7a791ee1bf6a87f06582f10e061a632ec28dcf5 /libstdc++-v3
parente4c9699234ba8ac217f1a030e6c7b62a5c6a1002 (diff)
downloadgcc-cbe41f67e27bad79b83b239b9ed447ec64fcadce.tar.gz
Prevent recursive instantiation in std::function
PR libstdc++/69005 PR libstdc++/69222 * include/std/functional (function::_Invoke): Remove, use result_of. (function::_Callable): Replace alias template with class template and use partial specialization instead of _NotSelf alias template. (function(_Functor)): Add "not self" constraint so that _Callable is not used while type is incomplete. * testsuite/20_util/function/69222.cc: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@232273 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/ChangeLog11
-rw-r--r--libstdc++-v3/include/std/functional17
-rw-r--r--libstdc++-v3/testsuite/20_util/function/69222.cc30
3 files changed, 47 insertions, 11 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index ad4cdc3fe01..d6fa5319b53 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,14 @@
+2016-01-12 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/69005
+ PR libstdc++/69222
+ * include/std/functional (function::_Invoke): Remove, use result_of.
+ (function::_Callable): Replace alias template with class template
+ and use partial specialization instead of _NotSelf alias template.
+ (function(_Functor)): Add "not self" constraint so that _Callable is
+ not used while type is incomplete.
+ * testsuite/20_util/function/69222.cc: New.
+
2016-01-11 Jonathan Wakely <jwakely@redhat.com>
PR libstdc++/60976
diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional
index 8023ab9aa4b..557156a358c 100644
--- a/libstdc++-v3/include/std/functional
+++ b/libstdc++-v3/include/std/functional
@@ -1846,20 +1846,14 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
{
typedef _Res _Signature_type(_ArgTypes...);
- template<typename _Functor>
- using _Invoke
- = decltype(std::__callable_functor(std::declval<_Functor&>())
- (std::declval<_ArgTypes>()...) );
+ template<typename _Func,
+ typename _Res2 = typename result_of<_Func(_ArgTypes...)>::type>
+ struct _Callable : __check_func_return_type<_Res2, _Res> { };
// Used so the return type convertibility checks aren't done when
// performing overload resolution for copy construction/assignment.
template<typename _Tp>
- using _NotSelf = __not_<is_same<_Tp, function>>;
-
- template<typename _Functor>
- using _Callable
- = __and_<_NotSelf<_Functor>,
- __check_func_return_type<_Invoke<_Functor>, _Res>>;
+ struct _Callable<function, _Tp> : false_type { };
template<typename _Cond, typename _Tp>
using _Requires = typename enable_if<_Cond::value, _Tp>::type;
@@ -1924,6 +1918,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
* reference_wrapper<F>, this function will not throw.
*/
template<typename _Functor,
+ typename = _Requires<__not_<is_same<_Functor, function>>, void>,
typename = _Requires<_Callable<_Functor>, void>>
function(_Functor);
@@ -2116,7 +2111,7 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
}
template<typename _Res, typename... _ArgTypes>
- template<typename _Functor, typename>
+ template<typename _Functor, typename, typename>
function<_Res(_ArgTypes...)>::
function(_Functor __f)
: _Function_base()
diff --git a/libstdc++-v3/testsuite/20_util/function/69222.cc b/libstdc++-v3/testsuite/20_util/function/69222.cc
new file mode 100644
index 00000000000..7c9dfecb547
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/function/69222.cc
@@ -0,0 +1,30 @@
+// Copyright (C) 2016 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++11" }
+// { dg-do compile }
+
+#include <functional>
+
+// Reduced from c++/69005
+struct Foo {
+ std::function<void(Foo)> f;
+};
+
+extern Foo exfoo;
+Foo f(exfoo);
+Foo& r = f = exfoo;