Patchwork fix libstdc++/57336

login
register
mail settings
Submitter Jonathan Wakely
Date May 21, 2013, 8:18 a.m.
Message ID <CAH6eHdSmvVwgtpFcoU+faEKy=Eb8G_ea4Yy2RYz1pG2tEh6Tog@mail.gmail.com>
Download mbox | patch
Permalink /patch/245219/
State New
Headers show

Comments

Jonathan Wakely - May 21, 2013, 8:18 a.m.
This broke due to some front end changes that disallow forming
function types that return abstract types.  std::reference_wrapper
always passes an lvalue reference to __invoke so it's correct to use
an lvalue reference as the result_of's template argument.

        PR libstdc++/57336
        * include/std/functional (__invoke): Do not form function types with
        abstract return type.
        * testsuite/20_util/reference_wrapper/invoke-3.cc: New.

Tested x86_64-linux, committed to trunk.

Jakub, this is a regression against 4.8.0, should it go on the branch too?
The change is small and isolated to code used by std::reference_wrapper.
commit 4b5557d04acb37fed7686e720ba0af0ed3428c56
Author: Jonathan Wakely <jwakely.gcc@gmail.com>
Date:   Tue May 21 08:52:16 2013 +0100

    	PR libstdc++/57336
    	* include/std/functional (__invoke): Do not form function types with
    	abstract return type.
    	* testsuite/20_util/reference_wrapper/invoke-3.cc: New.
Jakub Jelinek - May 21, 2013, 8:19 a.m.
On Tue, May 21, 2013 at 09:18:15AM +0100, Jonathan Wakely wrote:
> This broke due to some front end changes that disallow forming
> function types that return abstract types.  std::reference_wrapper
> always passes an lvalue reference to __invoke so it's correct to use
> an lvalue reference as the result_of's template argument.
> 
>         PR libstdc++/57336
>         * include/std/functional (__invoke): Do not form function types with
>         abstract return type.
>         * testsuite/20_util/reference_wrapper/invoke-3.cc: New.
> 
> Tested x86_64-linux, committed to trunk.
> 
> Jakub, this is a regression against 4.8.0, should it go on the branch too?
> The change is small and isolated to code used by std::reference_wrapper.

Ok.

	Jakub
Daniel Krügler - May 21, 2013, 8:24 a.m.
2013/5/21 Jonathan Wakely <jwakely.gcc@gmail.com>:
> This broke due to some front end changes that disallow forming
> function types that return abstract types.  std::reference_wrapper
> always passes an lvalue reference to __invoke so it's correct to use
> an lvalue reference as the result_of's template argument.

I agree. This was

http://cplusplus.github.io/LWG/lwg-defects.html#2017

wasn't it?

- Daniel
Jonathan Wakely - May 21, 2013, 8:35 a.m.
On 21 May 2013 09:24, Daniel Krügler wrote:
> 2013/5/21 Jonathan Wakely <jwakely.gcc@gmail.com>:
>> This broke due to some front end changes that disallow forming
>> function types that return abstract types.  std::reference_wrapper
>> always passes an lvalue reference to __invoke so it's correct to use
>> an lvalue reference as the result_of's template argument.
>
> I agree. This was
>
> http://cplusplus.github.io/LWG/lwg-defects.html#2017
>
> wasn't it?

Ah yes, thanks!  I'd fixed the signature in reference_wrapper but not
its __invoke() helper.

It's fixed on trunk and the 4.8 branch now.

>
> - Daniel

Patch

diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional
index 44d3fd5..63ba777 100644
--- a/libstdc++-v3/include/std/functional
+++ b/libstdc++-v3/include/std/functional
@@ -195,7 +195,7 @@  _GLIBCXX_HAS_NESTED_TYPE(result_type)
 	     (!is_member_pointer<_Functor>::value
 	      && !is_function<_Functor>::value
 	      && !is_function<typename remove_pointer<_Functor>::type>::value),
-	     typename result_of<_Functor(_Args&&...)>::type
+	     typename result_of<_Functor&(_Args&&...)>::type
 	   >::type
     __invoke(_Functor& __f, _Args&&... __args)
     {
diff --git a/libstdc++-v3/testsuite/20_util/reference_wrapper/invoke-3.cc b/libstdc++-v3/testsuite/20_util/reference_wrapper/invoke-3.cc
new file mode 100644
index 0000000..4291a67
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/reference_wrapper/invoke-3.cc
@@ -0,0 +1,37 @@ 
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+// Copyright (C) 2013 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/>.
+
+// 20.8.3.4 reference_wrapper invocation [refwrap.invoke]
+#include <functional>
+
+struct ABC
+{
+    virtual bool operator()() const = 0;
+};
+
+struct Concrete : ABC
+{
+    virtual bool operator()() const { return true; }
+};
+
+Concrete c;
+ABC& abc = c;
+
+auto b = std::cref(abc)();