This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] libstdc++/69222 Prevent recursive instantiation in std::function


This fixes PR 69222 and PR 69005 for gcc-5-branch, by ensuring we
don't try to determine the result of invoking the function(Functor)
constructor argument when the type is incomplete (because that might
require instantiating the constructor again, which recurses).

Jason fixed 69005 on trunk by making the front end skip that
constructor when performing overload resolution for copy construction,
because it cannot be instantiated to make a copy, but there is still a
problem on the branch, so I'm fixing it in the library. I'm making the
same change on trunk, because it's an improvement anyway.

Tested x86_64-linux, committed to trunk and gcc-5-branch.

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

diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional
index 139be61..717d1bf 100644
--- a/libstdc++-v3/include/std/functional
+++ b/libstdc++-v3/include/std/functional
@@ -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()
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 0000000..7c9dfec
--- /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;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]