public inbox for libstdc++-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/vendors/redhat/heads/gcc-10-branch)] libstdc++: Replace deduced return type in ranges::iter_move (PR 92894)
@ 2020-06-18 10:44 Jakub Jelinek
  0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2020-06-18 10:44 UTC (permalink / raw)
  To: gcc-cvs, libstdc++-cvs

https://gcc.gnu.org/g:6fedf28c7921f125be75a9f688a7b845a1b5663b

commit 6fedf28c7921f125be75a9f688a7b845a1b5663b
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Thu May 7 17:39:56 2020 +0100

    libstdc++: Replace deduced return type in ranges::iter_move (PR 92894)
    
    The deduced return type causes the instantiation of the function body,
    which can then require the instantiation of std::projected::operator*
    which is intentionally not defined.
    
    This patch uses a helper trait to define the return type, so that the
    function body doesn't need to be instantiated.
    
    Unlike on the master branch, this backport to gcc-10 does not change the
    iter_rvalue_reference_t alias template and __indirectly_readable_impl
    concept to use the new trait.
    
    Backport from mainline
    2020-05-01  Jonathan Wakely  <jwakely@redhat.com>
                Patrick Palka  <ppalka@redhat.com>
    
            PR libstdc++/92894
            * include/bits/iterator_concepts.h (ranges::__cust_imove::_IMove):
            Add trait to determine return type and an alias for it.
            (ranges::__cust_imove::_IMove::operator()): Use __result instead of
            deduced return type.
            * testsuite/24_iterators/customization_points/92894.cc: New test.
            * testsuite/24_iterators/indirect_callable/92894.cc: New test.
    
    Co-authored-by: Patrick Palka <ppalka@redhat.com>

Diff:
---
 libstdc++-v3/ChangeLog                             | 14 ++++++
 libstdc++-v3/include/bits/iterator_concepts.h      | 28 +++++++++--
 .../24_iterators/customization_points/92894.cc     | 52 ++++++++++++++++++++
 .../24_iterators/indirect_callable/92894.cc        | 55 ++++++++++++++++++++++
 4 files changed, 144 insertions(+), 5 deletions(-)

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 70e296622e7..55d975b84fc 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,17 @@
+2020-05-07  Jonathan Wakely  <jwakely@redhat.com>
+
+	Backport from mainline
+	2020-05-01  Jonathan Wakely  <jwakely@redhat.com>
+		    Patrick Palka  <ppalka@redhat.com>
+
+	PR libstdc++/92894
+	* include/bits/iterator_concepts.h (ranges::__cust_imove::_IMove):
+	Add trait to determine return type and an alias for it.
+	(ranges::__cust_imove::_IMove::operator()): Use __result instead of
+	deduced return type.
+	* testsuite/24_iterators/customization_points/92894.cc: New test.
+	* testsuite/24_iterators/indirect_callable/92894.cc: New test.
+
 2020-05-07  Release Manager
 
 	* GCC 10.1.0 released.
diff --git a/libstdc++-v3/include/bits/iterator_concepts.h b/libstdc++-v3/include/bits/iterator_concepts.h
index b598532089e..c5b6247cde7 100644
--- a/libstdc++-v3/include/bits/iterator_concepts.h
+++ b/libstdc++-v3/include/bits/iterator_concepts.h
@@ -89,6 +89,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       struct _IMove
       {
       private:
+	template<typename _Tp>
+	  struct __result
+	  { using type = iter_reference_t<_Tp>; };
+
+	template<typename _Tp>
+	  requires __adl_imove<_Tp>
+	  struct __result<_Tp>
+	  { using type = decltype(iter_move(std::declval<_Tp>())); };
+
+	template<typename _Tp>
+	  requires (!__adl_imove<_Tp>)
+	  && is_lvalue_reference_v<iter_reference_t<_Tp>>
+	  struct __result<_Tp>
+	  { using type = remove_reference_t<iter_reference_t<_Tp>>&&; };
+
 	template<typename _Tp>
 	  static constexpr bool
 	  _S_noexcept()
@@ -100,16 +115,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  }
 
       public:
-	template<typename _Tp>
-	  requires __adl_imove<_Tp> || requires(_Tp& __e) { *__e; }
-	  constexpr decltype(auto)
+	// The result type of iter_move(std::declval<_Tp>())
+	template<std::__detail::__dereferenceable _Tp>
+	  using __type = typename __result<_Tp>::type;
+
+	template<std::__detail::__dereferenceable _Tp>
+	  constexpr __type<_Tp>
 	  operator()(_Tp&& __e) const
 	  noexcept(_S_noexcept<_Tp>())
 	  {
 	    if constexpr (__adl_imove<_Tp>)
 	      return iter_move(static_cast<_Tp&&>(__e));
-	    else if constexpr (is_reference_v<iter_reference_t<_Tp>>)
-	      return std::move(*__e);
+	    else if constexpr (is_lvalue_reference_v<iter_reference_t<_Tp>>)
+	      return static_cast<__type<_Tp>>(*__e);
 	    else
 	      return *__e;
 	  }
diff --git a/libstdc++-v3/testsuite/24_iterators/customization_points/92894.cc b/libstdc++-v3/testsuite/24_iterators/customization_points/92894.cc
new file mode 100644
index 00000000000..197268fe5e3
--- /dev/null
+++ b/libstdc++-v3/testsuite/24_iterators/customization_points/92894.cc
@@ -0,0 +1,52 @@
+// Copyright (C) 2020 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++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <iterator>
+
+using namespace std;
+
+// Define our own of version of indirectly_readable_impl here,
+// to check the use of iter_move even if the real concept in
+// <bits/iterator_concepts.h> no longer uses iter_move.
+template<class In>
+concept indirectly_readable_impl
+  = requires(const In in)
+      {
+	typename iter_value_t<In>;
+	typename iter_reference_t<In>;
+	typename iter_rvalue_reference_t<In>;
+	{ *in } -> same_as<iter_reference_t<In>>;
+	{ ranges::iter_move(in) } -> same_as<iter_rvalue_reference_t<In>>;
+      };
+
+template<class T> requires indirectly_readable_impl<projected<T*, identity>>
+  void algo(T)
+  { }
+
+void
+test01()
+{
+  // PR libstdc++/92894
+  // Verify that the use of range::iter_move above doesn't cause odr-use of
+  // projected<local-class-type, identity>::operator* (which is not defined).
+  struct X { };
+  X a;
+  algo(a);
+}
diff --git a/libstdc++-v3/testsuite/24_iterators/indirect_callable/92894.cc b/libstdc++-v3/testsuite/24_iterators/indirect_callable/92894.cc
new file mode 100644
index 00000000000..3408c76bde1
--- /dev/null
+++ b/libstdc++-v3/testsuite/24_iterators/indirect_callable/92894.cc
@@ -0,0 +1,55 @@
+// Copyright (C) 2020 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++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <iterator>
+
+using std::projected;
+using std::identity;
+using std::indirect_unary_predicate;
+
+template<typename T,
+	 indirect_unary_predicate<projected<T*, identity>> Pred>
+  constexpr void
+  all_of(T*, Pred)
+  { }
+
+void
+test01()
+{
+  // PR libstdc++/92894
+  struct X { };
+  X x;
+  all_of(&x, [](X&) { return false; });
+}
+
+template<class R, class Proj = identity,
+	 indirect_unary_predicate<projected<R, Proj>> Pred>
+  constexpr void
+  find_if(R, Pred, Proj = {})
+  { }
+
+void
+test02()
+{
+  // PR 94241
+  struct s { int m; };
+  s r[] = { s{0}, s{1}, s{2}, s{3} };
+  find_if(r, [](auto const) { return true; });
+}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-06-18 10:44 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-18 10:44 [gcc(refs/vendors/redhat/heads/gcc-10-branch)] libstdc++: Replace deduced return type in ranges::iter_move (PR 92894) Jakub Jelinek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).