commit 540303f8e8f24a89ecd3698c70efe9ab753ef9d9
Author: redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Tue Jan 12 14:55:00 2016 +0000
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/branches/gcc-5-branch@232274 138bc75d-0d04-0410-961f-82ee72b054a4
@@ -1977,19 +1977,14 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
{
typedef _Res _Signature_type(_ArgTypes...);
- template<typename _Functor>
- using _Invoke = decltype(__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;
@@ -2054,6 +2049,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);
@@ -2246,7 +2242,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()
new file mode 100644
@@ -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;