]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Prevent recursive instantiation in std::function
authorredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 12 Jan 2016 14:54:33 +0000 (14:54 +0000)
committerredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 12 Jan 2016 14:54:33 +0000 (14:54 +0000)
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

libstdc++-v3/ChangeLog
libstdc++-v3/include/std/functional
libstdc++-v3/testsuite/20_util/function/69222.cc [new file with mode: 0644]

index ad4cdc3fe01bb8f41590366b8960e976be5fce9d..d6fa5319b53f1566ef581f57f05e8a11ccaafd1d 100644 (file)
@@ -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
index 8023ab9aa4b2a717b6fd9e53e4874c8b993f3109..557156a358c32653e4513955ab9682fe35e76174 100644 (file)
@@ -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 (file)
index 0000000..7c9dfec
--- /dev/null
@@ -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;