public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [committed] libstdc++: Implement LWG issues 3398, 3379, 3304, 3321, 3280, 3335
@ 2020-02-19 12:47 Jonathan Wakely
  2020-02-19 13:01 ` Jonathan Wakely
  2020-02-19 15:45 ` [committed] libstdc++: Implement LWG issues 3320, 3369, 3200, 3348, 3237 Jonathan Wakely
  0 siblings, 2 replies; 5+ messages in thread
From: Jonathan Wakely @ 2020-02-19 12:47 UTC (permalink / raw)
  To: libstdc++, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 410 bytes --]

Add ranges_size_t and rename all_view (LWG 3335)
Remove converting constructors from views (LWG 3280)
uninitialized_construct_using_allocator should use construct_at (LWG 3321)
Add nodiscard to polymorphic_allocator members (LWG 3304)
"safe" in several library names is misleading (LWG 3379)
tuple_element_t is also wrong for const subrange (LWG 3398)

Tested powerpc64le-linux, committed to master.


[-- Attachment #2: patch.txt --]
[-- Type: text/x-patch, Size: 99068 bytes --]

commit aca60ecff35837a1af9383cf67ee7d1c0a718b28
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Feb 19 12:30:10 2020 +0000

    libstdc++: Add ranges_size_t and rename all_view (LWG 3335)
    
            * include/bits/range_access.h (range_size_t): Define alias template.
            * include/std/ranges (all_view): Rename to views::all_t (LWG 3335).
            * testsuite/std/ranges/adaptors/filter.cc: Adjust to new name.

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 9ccba4345d5..f01b78da118 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,9 @@
 2020-02-19  Jonathan Wakely  <jwakely@redhat.com>
 
+	* include/bits/range_access.h (range_size_t): Define alias template.
+	* include/std/ranges (all_view): Rename to views::all_t (LWG 3335).
+	* testsuite/std/ranges/adaptors/filter.cc: Adjust to new name.
+
 	* include/std/ranges (filter_view, transform_view, take_view)
 	(join_view, split_view, reverse_view): Remove commented-out converting
 	constructors (LWG 3280).
diff --git a/libstdc++-v3/include/bits/range_access.h b/libstdc++-v3/include/bits/range_access.h
index e2a2c28c7d2..e7a19305d23 100644
--- a/libstdc++-v3/include/bits/range_access.h
+++ b/libstdc++-v3/include/bits/range_access.h
@@ -905,6 +905,9 @@ namespace ranges
     concept sized_range = range<_Tp>
       && requires(_Tp& __t) { ranges::size(__t); };
 
+  template<sized_range _Range>
+    using range_size_t = decltype(ranges::size(std::declval<_Range&>()));
+
   // [range.refinements]
 
   /// A range for which ranges::begin returns an output iterator.
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index cf4c19ffaab..b0806750a08 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -1236,10 +1236,11 @@ namespace views
 	else
 	  return subrange{std::forward<_Range>(__r)};
       };
-  } // namespace views
 
-  template<viewable_range _Range>
-    using all_view = decltype(views::all(declval<_Range>()));
+    template<viewable_range _Range>
+      using all_t = decltype(all(std::declval<_Range>()));
+
+  } // namespace views
 
   // XXX: the following algos are copied from ranges_algo.h to avoid a circular
   // dependency with that header.
@@ -1503,7 +1504,7 @@ namespace views
     };
 
   template<typename _Range, typename _Pred>
-    filter_view(_Range&&, _Pred) -> filter_view<all_view<_Range>, _Pred>;
+    filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>;
 
   namespace views
   {
@@ -1836,7 +1837,7 @@ namespace views
     };
 
   template<typename _Range, typename _Fp>
-    transform_view(_Range&&, _Fp) -> transform_view<all_view<_Range>, _Fp>;
+    transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;
 
   namespace views
   {
@@ -1974,7 +1975,7 @@ namespace views
 
   template<range _Range>
     take_view(_Range&&, range_difference_t<_Range>)
-      -> take_view<all_view<_Range>>;
+      -> take_view<views::all_t<_Range>>;
 
   namespace views
   {
@@ -2066,7 +2067,7 @@ namespace views
 
   template<typename _Range, typename _Pred>
     take_while_view(_Range&&, _Pred)
-      -> take_while_view<all_view<_Range>, _Pred>;
+      -> take_while_view<views::all_t<_Range>, _Pred>;
 
   namespace views
   {
@@ -2143,7 +2144,7 @@ namespace views
 
   template<typename _Range>
     drop_view(_Range&&, range_difference_t<_Range>)
-      -> drop_view<all_view<_Range>>;
+      -> drop_view<views::all_t<_Range>>;
 
   namespace views
   {
@@ -2199,7 +2200,7 @@ namespace views
 
   template<typename _Range, typename _Pred>
     drop_while_view(_Range&&, _Pred)
-      -> drop_while_view<all_view<_Range>, _Pred>;
+      -> drop_while_view<views::all_t<_Range>, _Pred>;
 
   namespace views
   {
@@ -2450,7 +2451,7 @@ namespace views
       // XXX: _M_inner is "present only when !is_reference_v<_InnerRange>"
       [[no_unique_address]]
 	conditional_t<!is_reference_v<_InnerRange>,
-		      all_view<_InnerRange>, __detail::_Empty> _M_inner;
+		      views::all_t<_InnerRange>, __detail::_Empty> _M_inner;
 
     public:
       join_view() = default;
@@ -2514,7 +2515,7 @@ namespace views
     };
 
   template<typename _Range>
-    explicit join_view(_Range&&) -> join_view<all_view<_Range>>;
+    explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
 
   namespace views
   {
@@ -2838,7 +2839,7 @@ namespace views
       { }
 
       template<input_range _Range>
-	requires constructible_from<_Vp, all_view<_Range>>
+	requires constructible_from<_Vp, views::all_t<_Range>>
 	  && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
 	constexpr
 	split_view(_Range&& __r, range_value_t<_Range> __e)
@@ -2893,11 +2894,11 @@ namespace views
 
   template<typename _Range, typename _Pred>
     split_view(_Range&&, _Pred&&)
-      -> split_view<all_view<_Range>, all_view<_Pred>>;
+      -> split_view<views::all_t<_Range>, views::all_t<_Pred>>;
 
   template<input_range _Range>
     split_view(_Range&&, range_value_t<_Range>)
-      -> split_view<all_view<_Range>, single_view<range_value_t<_Range>>>;
+      -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
 
   namespace views
   {
@@ -2945,7 +2946,7 @@ namespace views
       /* XXX: LWG 3280 didn't remove this constructor, but I think it should?
       template<viewable_range _Range>
 	requires (!common_range<_Range>)
-	  && constructible_from<_Vp, all_view<_Range>>
+	  && constructible_from<_Vp, views::all_t<_Range>>
 	constexpr explicit
 	common_view(_Range&& __r)
 	  : _M_base(views::all(std::forward<_Range>(__r)))
@@ -3010,7 +3011,7 @@ namespace views
     };
 
   template<typename _Range>
-    common_view(_Range&&) -> common_view<all_view<_Range>>;
+    common_view(_Range&&) -> common_view<views::all_t<_Range>>;
 
   namespace views
   {
@@ -3083,7 +3084,7 @@ namespace views
     };
 
   template<typename _Range>
-    reverse_view(_Range&&) -> reverse_view<all_view<_Range>>;
+    reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
 
   namespace views
   {
@@ -3356,10 +3357,10 @@ namespace views
     };
 
   template<typename _Range>
-    using keys_view = elements_view<all_view<_Range>, 0>;
+    using keys_view = elements_view<views::all_t<_Range>, 0>;
 
   template<typename _Range>
-    using values_view = elements_view<all_view<_Range>, 1>;
+    using values_view = elements_view<views::all_t<_Range>, 1>;
 
   namespace views
   {
@@ -3367,7 +3368,8 @@ namespace views
     inline constexpr __adaptor::_RangeAdaptorClosure elements
       = [] <viewable_range _Range> (_Range&& __r)
       {
-	return elements_view<all_view<_Range>, _Nm>{std::forward<_Range>(__r)};
+	using _El = elements_view<views::all_t<_Range>, _Nm>;
+	return _El{std::forward<_Range>(__r)};
       };
 
     inline constexpr __adaptor::_RangeAdaptorClosure keys = elements<0>;
diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/filter.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/filter.cc
index 4edbf0b657d..4e41232cd5c 100644
--- a/libstdc++-v3/testsuite/std/ranges/adaptors/filter.cc
+++ b/libstdc++-v3/testsuite/std/ranges/adaptors/filter.cc
@@ -43,7 +43,7 @@ test01()
   static_assert(!ranges::sized_range<R>);
   static_assert(ranges::bidirectional_range<R>);
   static_assert(!ranges::random_access_range<R>);
-  static_assert(ranges::range<ranges::all_view<R>>);
+  static_assert(ranges::range<views::all_t<R>>);
   VERIFY( ranges::equal(v, (int[]){1,3,5}) );
   VERIFY( ranges::equal(v | views::reverse, (int[]){5,3,1}) );
   VERIFY( v.pred()(3) == true );

commit 4cc3b275d310dbf5982544cb88c11630349f414c
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Feb 19 12:26:19 2020 +0000

    libstdc++: Remove converting constructors from views (LWG 3280)
    
            * include/std/ranges (filter_view, transform_view, take_view)
            (join_view, split_view, reverse_view): Remove commented-out converting
            constructors (LWG 3280).

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 5408a89c7fb..9ccba4345d5 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,9 @@
 2020-02-19  Jonathan Wakely  <jwakely@redhat.com>
 
+	* include/std/ranges (filter_view, transform_view, take_view)
+	(join_view, split_view, reverse_view): Remove commented-out converting
+	constructors (LWG 3280).
+
 	* include/std/memory (uninitialized_construct_using_allocator): Use
 	std::construct_at (LWG 3321).
 
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index 4bfda88c319..cf4c19ffaab 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -1470,17 +1470,6 @@ namespace views
 	: _M_base(std::move(__base)), _M_pred(std::move(__pred))
       { }
 
-      /* XXX: P3280 removes this constructor
-      template<input_range _Range>
-	requires viewable_range<_Range>
-	  && constructible_from<_Vp, all_view<_Range>>
-	constexpr
-	filter_view(_Range&& __r, _Pred __pred)
-	  : _M_base(views::all(std::forward<_Range>(__r))),
-	    _M_pred(std::move(__pred))
-	{ }
-      */
-
       constexpr _Vp
       base() const& requires copy_constructible<_Vp>
       { return _M_base; }
@@ -1799,17 +1788,6 @@ namespace views
 	: _M_base(std::move(__base)), _M_fun(std::move(__fun))
       { }
 
-      /* XXX: P3280 removes this constructor
-      template<input_range _Range>
-	requires viewable_range<_Range>
-	  && constructible_from<_Vp, all_view<_Range>>
-	constexpr
-	transform_view(_Range&& __r, _Fp __fun)
-	  : _M_base(views::all(std::forward<_Range>(__r)))
-	{
-	}
-	*/
-
       constexpr _Vp
       base() const& requires copy_constructible<_Vp>
       { return _M_base ; }
@@ -1915,15 +1893,6 @@ namespace views
 	: _M_base(std::move(base)), _M_count(std::move(__count))
       { }
 
-      /* XXX: P3280 removes this constructor
-      template<viewable_range _Range>
-	requires constructible_from<_Vp, all_view<_Range>>
-      constexpr
-      take_view(_Range&& __r, range_difference_t<_Vp> __count)
-	: _M_base(views::all(std::forward<_Range>(__r))), _M_count(__count)
-      { }
-      */
-
       constexpr _Vp
       base() const& requires copy_constructible<_Vp>
       { return _M_base; }
@@ -2491,16 +2460,6 @@ namespace views
 	: _M_base(std::move(__base))
       { }
 
-      /* XXX: P3280 removes this constructor
-      template<input_range _Range>
-	requires viewable_range<_Range>
-	  && constructible_from<_Vp, all_view<_Range>>
-      constexpr explicit
-      join_view(_Range&& __r)
-	: _M_base(views::all(std::forward<_Range>(__r)))
-      { }
-      */
-
       constexpr _Vp
       base() const& requires copy_constructible<_Vp>
       { return _M_base; }
@@ -2878,17 +2837,6 @@ namespace views
 	: _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
       { }
 
-      /* XXX: P3280 removes this constructor
-      template<input_range _Range, forward_range _Pred>
-	requires constructible_from<_Vp, all_view<_Range>>
-	  && constructible_from<_Pattern, all_view<_Pred>>
-	constexpr
-	split_view(_Range&& __r, _Pred&& __p)
-	  : _M_base(views::all(std::forward<_Range>(__r))),
-	    _M_pattern(views::all(std::forward<_Pred>(__p)))
-      { }
-      */
-
       template<input_range _Range>
 	requires constructible_from<_Vp, all_view<_Range>>
 	  && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
@@ -2994,14 +2942,15 @@ namespace views
 	: _M_base(std::move(__r))
       { }
 
-      /* XXX: P3280 doesn't remove this constructor, but I think it should?
+      /* XXX: LWG 3280 didn't remove this constructor, but I think it should?
       template<viewable_range _Range>
-	requires (!common_range<_Range>) && constructible_from<_Vp, all_view<_Range>>
+	requires (!common_range<_Range>)
+	  && constructible_from<_Vp, all_view<_Range>>
 	constexpr explicit
 	common_view(_Range&& __r)
 	  : _M_base(views::all(std::forward<_Range>(__r)))
 	{ }
-	*/
+      */
 
       constexpr _Vp
       base() const& requires copy_constructible<_Vp>
@@ -3092,15 +3041,6 @@ namespace views
 	: _M_base(std::move(__r))
 	{ }
 
-      /* XXX: P3280 removes this constructor
-      template<viewable_range _Range>
-	requires bidirectional_range<_Range> && constructible_from<_Vp, all_view<_Range>>
-	constexpr explicit
-	reverse_view(_Range&& __r)
-	  : _M_base(views::all(std::forward<_Range>(__r)))
-	{ }
-	*/
-
       constexpr _Vp
       base() const& requires copy_constructible<_Vp>
       { return _M_base; }

commit 5f3641d0c430523d839298a6876f907523811485
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Feb 19 12:14:54 2020 +0000

    libstdc++: uninitialized_construct_using_allocator should use construct_at (LWG 3321)
    
            * include/std/memory (uninitialized_construct_using_allocator): Use
            std::construct_at (LWG 3321).

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index eb83c632adc..5408a89c7fb 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,8 @@
 2020-02-19  Jonathan Wakely  <jwakely@redhat.com>
 
+	* include/std/memory (uninitialized_construct_using_allocator): Use
+	std::construct_at (LWG 3321).
+
 	* include/std/memory_resource (polymorphic_allocator::allocate_bytes)
 	(polymorphic_allocator::allocate_object)
 	(polymorphic_allocator::new_object): Add nodiscard attribute (LWG3304).
diff --git a/libstdc++-v3/include/std/memory b/libstdc++-v3/include/std/memory
index 14aedb70dac..aaee6e42c1a 100644
--- a/libstdc++-v3/include/std/memory
+++ b/libstdc++-v3/include/std/memory
@@ -387,9 +387,10 @@ get_pointer_safety() noexcept { return pointer_safety::relaxed; }
     uninitialized_construct_using_allocator(_Tp* __p, const _Alloc& __a,
 					    _Args&&... __args)
     {
-      void* __vp = const_cast<void*>(static_cast<const volatile void*>(__p));
-      return ::new(__vp) _Tp(std::make_obj_using_allocator<_Tp>(__a,
-	    std::forward<_Args>(__args)...));
+      return std::apply([&](auto&&... __xs) {
+	return std::construct_at(__p, std::forward<decltype(__xs)>(__xs)...);
+      }, std::uses_allocator_construction_args<_Tp>(__a,
+	std::forward<_Args>(__args)...));
     }
 // @}
 

commit 020a03eec7054adb10396067fab69d0ace00aada
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Feb 19 12:04:53 2020 +0000

    libstdc++: Add nodiscard to polymorphic_allocator members (LWG 3304)
    
            * include/std/memory_resource (polymorphic_allocator::allocate_bytes)
            (polymorphic_allocator::allocate_object)
            (polymorphic_allocator::new_object): Add nodiscard attribute (LWG3304).

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 045f0badfae..eb83c632adc 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,9 @@
 2020-02-19  Jonathan Wakely  <jwakely@redhat.com>
 
+	* include/std/memory_resource (polymorphic_allocator::allocate_bytes)
+	(polymorphic_allocator::allocate_object)
+	(polymorphic_allocator::new_object): Add nodiscard attribute (LWG3304).
+
 	LWG 3379. "safe" in several library names is misleading
 	* include/bits/range_access.h (enable_safe_range): Rename to
 	enable_borrowed_range.
diff --git a/libstdc++-v3/include/std/memory_resource b/libstdc++-v3/include/std/memory_resource
index 70c56d1d7e6..73f77bdcadf 100644
--- a/libstdc++-v3/include/std/memory_resource
+++ b/libstdc++-v3/include/std/memory_resource
@@ -178,7 +178,7 @@ namespace pmr
       { _M_resource->deallocate(__p, __n * sizeof(_Tp), alignof(_Tp)); }
 
 #if __cplusplus > 201703L
-      void*
+      [[nodiscard]] void*
       allocate_bytes(size_t __nbytes,
 		     size_t __alignment = alignof(max_align_t))
       { return _M_resource->allocate(__nbytes, __alignment); }
@@ -189,7 +189,7 @@ namespace pmr
       { _M_resource->deallocate(__p, __nbytes, __alignment); }
 
       template<typename _Up>
-	_Up*
+	[[nodiscard]] _Up*
 	allocate_object(size_t __n = 1)
 	{
 	  if ((__detail::__int_limits<size_t>::max() / sizeof(_Up)) < __n)
@@ -204,7 +204,7 @@ namespace pmr
 	{ deallocate_bytes(__p, __n * sizeof(_Up), alignof(_Up)); }
 
       template<typename _Up, typename... _CtorArgs>
-	_Up*
+	[[nodiscard]] _Up*
 	new_object(_CtorArgs&&... __ctor_args)
 	{
 	  _Up* __p = allocate_object<_Up>();

commit 15411a6453444ef49940822380e39e6a1d174fac
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Feb 19 11:54:19 2020 +0000

    libstdc++: "safe" in several library names is misleading (LWG 3379)
    
            * include/bits/range_access.h (enable_safe_range): Rename to
            enable_borrowed_range.
            (__detail::__maybe_safe_range): Rename to __maybe_borrowed_range.
            (safe_range): Rename to borrowed_range.
            * include/bits/ranges_algo.h: Adjust to use new names.
            * include/bits/ranges_algobase.h: Likewise.
            * include/bits/ranges_uninitialized.h: Likewise.
            * include/std/ranges: Likewise.
            (safe_iterator_t): Rename to borrowed_iterator_t.
            (safe_subrange_t): Rename to borrowed_subrange_t.
            * include/std/span: Adjust to use new names.
            * include/std/string_view: Likewise.
            * include/experimental/string_view: Likewise.
            * testsuite/std/ranges/access/begin.cc: Likewise.
            * testsuite/std/ranges/access/cbegin.cc: Likewise.
            * testsuite/std/ranges/access/cdata.cc: Likewise.
            * testsuite/std/ranges/access/cend.cc: Likewise.
            * testsuite/std/ranges/access/crbegin.cc: Likewise.
            * testsuite/std/ranges/access/crend.cc: Likewise.
            * testsuite/std/ranges/access/data.cc: Likewise.
            * testsuite/std/ranges/access/end.cc: Likewise.
            * testsuite/std/ranges/access/rbegin.cc: Likewise.
            * testsuite/std/ranges/access/rend.cc: Likewise.
            * testsuite/std/ranges/safe_range.cc: Likewise.
            * testsuite/std/ranges/safe_range_types.cc: Likewise.
            * testsuite/util/testsuite_iterators.h: Likewise.

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index f69507d667f..045f0badfae 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,33 @@
 2020-02-19  Jonathan Wakely  <jwakely@redhat.com>
 
+	LWG 3379. "safe" in several library names is misleading
+	* include/bits/range_access.h (enable_safe_range): Rename to
+	enable_borrowed_range.
+	(__detail::__maybe_safe_range): Rename to __maybe_borrowed_range.
+	(safe_range): Rename to borrowed_range.
+	* include/bits/ranges_algo.h: Adjust to use new names.
+	* include/bits/ranges_algobase.h: Likewise.
+	* include/bits/ranges_uninitialized.h: Likewise.
+	* include/std/ranges: Likewise.
+	(safe_iterator_t): Rename to borrowed_iterator_t.
+	(safe_subrange_t): Rename to borrowed_subrange_t.
+	* include/std/span: Adjust to use new names.
+	* include/std/string_view: Likewise.
+	* include/experimental/string_view: Likewise.
+	* testsuite/std/ranges/access/begin.cc: Likewise.
+	* testsuite/std/ranges/access/cbegin.cc: Likewise.
+	* testsuite/std/ranges/access/cdata.cc: Likewise.
+	* testsuite/std/ranges/access/cend.cc: Likewise.
+	* testsuite/std/ranges/access/crbegin.cc: Likewise.
+	* testsuite/std/ranges/access/crend.cc: Likewise.
+	* testsuite/std/ranges/access/data.cc: Likewise.
+	* testsuite/std/ranges/access/end.cc: Likewise.
+	* testsuite/std/ranges/access/rbegin.cc: Likewise.
+	* testsuite/std/ranges/access/rend.cc: Likewise.
+	* testsuite/std/ranges/safe_range.cc: Likewise.
+	* testsuite/std/ranges/safe_range_types.cc: Likewise.
+	* testsuite/util/testsuite_iterators.h: Likewise.
+
 	* include/std/ranges (tuple_element<0, const subrange<I, S, K>>)
 	(tuple_element<1, const subrange<I, S, K>>): Add partial
 	specializations (LWG 3398).
diff --git a/libstdc++-v3/include/bits/range_access.h b/libstdc++-v3/include/bits/range_access.h
index 8bac0efc6ed..e2a2c28c7d2 100644
--- a/libstdc++-v3/include/bits/range_access.h
+++ b/libstdc++-v3/include/bits/range_access.h
@@ -344,7 +344,7 @@ namespace ranges
     inline constexpr bool disable_sized_range = false;
 
   template<typename _Tp>
-    inline constexpr bool enable_safe_range = false;
+    inline constexpr bool enable_borrowed_range = false;
 
   namespace __detail
   {
@@ -357,16 +357,17 @@ namespace ranges
       using __make_unsigned_like_t
 	= conditional_t<_MaxDiff, __max_size_type, make_unsigned_t<_Tp>>;
 
-    // Part of the constraints of ranges::safe_range
+    // Part of the constraints of ranges::borrowed_range
     template<typename _Tp>
-      concept __maybe_safe_range
-	= is_lvalue_reference_v<_Tp> || enable_safe_range<remove_cvref_t<_Tp>>;
+      concept __maybe_borrowed_range
+	= is_lvalue_reference_v<_Tp>
+	  || enable_borrowed_range<remove_cvref_t<_Tp>>;
 
   } // namespace __detail
 
   namespace __cust_access
   {
-    using std::ranges::__detail::__maybe_safe_range;
+    using std::ranges::__detail::__maybe_borrowed_range;
     using std::__detail::__class_or_enum;
 
     template<typename _Tp>
@@ -407,7 +408,7 @@ namespace ranges
 	}
 
     public:
-      template<__maybe_safe_range _Tp>
+      template<__maybe_borrowed_range _Tp>
 	requires is_array_v<remove_reference_t<_Tp>> || __member_begin<_Tp>
 	  || __adl_begin<_Tp>
 	constexpr auto
@@ -459,7 +460,7 @@ namespace ranges
 	}
 
     public:
-      template<__maybe_safe_range _Tp>
+      template<__maybe_borrowed_range _Tp>
 	requires is_array_v<remove_reference_t<_Tp>> || __member_end<_Tp>
 	|| __adl_end<_Tp>
 	constexpr auto
@@ -559,7 +560,7 @@ namespace ranges
 	}
 
     public:
-      template<__maybe_safe_range _Tp>
+      template<__maybe_borrowed_range _Tp>
 	requires __member_rbegin<_Tp> || __adl_rbegin<_Tp> || __reversable<_Tp>
 	constexpr auto
 	operator()(_Tp&& __t) const
@@ -616,7 +617,7 @@ namespace ranges
 	}
 
     public:
-      template<__maybe_safe_range _Tp>
+      template<__maybe_borrowed_range _Tp>
 	requires __member_rend<_Tp> || __adl_rend<_Tp> || __reversable<_Tp>
 	constexpr auto
 	operator()(_Tp&& __t) const
@@ -875,9 +876,10 @@ namespace ranges
 	ranges::end(__t);
       };
 
-  /// [range.range] The safe_range concept.
+  /// [range.range] The borrowed_range concept.
   template<typename _Tp>
-    concept safe_range = range<_Tp> && __detail::__maybe_safe_range<_Tp>;
+    concept borrowed_range
+      = range<_Tp> && __detail::__maybe_borrowed_range<_Tp>;
 
   template<range _Range>
     using iterator_t = decltype(ranges::begin(std::declval<_Range&>()));
diff --git a/libstdc++-v3/include/bits/ranges_algo.h b/libstdc++-v3/include/bits/ranges_algo.h
index a69181e12cb..7de1072abf0 100644
--- a/libstdc++-v3/include/bits/ranges_algo.h
+++ b/libstdc++-v3/include/bits/ranges_algo.h
@@ -190,7 +190,7 @@ namespace ranges
     template<input_range _Range, typename _Proj = identity,
 	     indirectly_unary_invocable<projected<iterator_t<_Range>, _Proj>>
 	       _Fun>
-      constexpr for_each_result<safe_iterator_t<_Range>, _Fun>
+      constexpr for_each_result<borrowed_iterator_t<_Range>, _Fun>
       operator()(_Range&& __r, _Fun __f, _Proj __proj = {}) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -253,7 +253,7 @@ namespace ranges
       requires indirect_binary_predicate<ranges::equal_to,
 					 projected<iterator_t<_Range>, _Proj>,
 					 const _Tp*>
-      constexpr safe_iterator_t<_Range>
+      constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r, const _Tp& __value, _Proj __proj = {}) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -281,7 +281,7 @@ namespace ranges
     template<input_range _Range, typename _Proj = identity,
 	     indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
 	       _Pred>
-      constexpr safe_iterator_t<_Range>
+      constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -309,7 +309,7 @@ namespace ranges
     template<input_range _Range, typename _Proj = identity,
 	     indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
 	       _Pred>
-      constexpr safe_iterator_t<_Range>
+      constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -345,7 +345,7 @@ namespace ranges
 	     typename _Proj1 = identity, typename _Proj2 = identity>
       requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>,
 				     _Pred, _Proj1, _Proj2>
-      constexpr safe_iterator_t<_Range1>
+      constexpr borrowed_iterator_t<_Range1>
       operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {},
 		 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
       {
@@ -536,7 +536,7 @@ namespace ranges
 	     typename _Proj1 = identity, typename _Proj2 = identity>
       requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>,
 				     _Pred, _Proj1, _Proj2>
-      constexpr safe_subrange_t<_Range1>
+      constexpr borrowed_subrange_t<_Range1>
       operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {},
 		 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
       {
@@ -625,7 +625,7 @@ namespace ranges
 	     typename _Pred = ranges::equal_to, typename _Proj = identity>
       requires indirectly_comparable<iterator_t<_Range>, const _Tp*,
 				     _Pred, _Proj>
-      constexpr safe_subrange_t<_Range>
+      constexpr borrowed_subrange_t<_Range>
       operator()(_Range&& __r, range_difference_t<_Range> __count,
 	       const _Tp& __value, _Pred __pred = {}, _Proj __proj = {}) const
       {
@@ -701,7 +701,7 @@ namespace ranges
 	     typename _Proj1 = identity, typename _Proj2 = identity>
       requires indirectly_comparable<iterator_t<_Range1>, iterator_t<_Range2>,
 				     _Pred, _Proj1, _Proj2>
-      constexpr safe_subrange_t<_Range1>
+      constexpr borrowed_subrange_t<_Range1>
       operator()(_Range1&& __r1, _Range2&& __r2, _Pred __pred = {},
 		 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
       {
@@ -742,7 +742,7 @@ namespace ranges
 	     indirect_binary_predicate<
 	       projected<iterator_t<_Range>, _Proj>,
 	       projected<iterator_t<_Range>, _Proj>> _Pred = ranges::equal_to>
-      constexpr safe_iterator_t<_Range>
+      constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r, _Pred __pred = {}, _Proj __proj = {}) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -866,7 +866,7 @@ namespace ranges
 	     indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
 	       _Pred>
       requires indirectly_copyable<iterator_t<_Range>, _Out>
-      constexpr copy_if_result<safe_iterator_t<_Range>, _Out>
+      constexpr copy_if_result<borrowed_iterator_t<_Range>, _Out>
       operator()(_Range&& __r, _Out __result,
 		 _Pred __pred, _Proj __proj = {}) const
       {
@@ -898,8 +898,8 @@ namespace ranges
 
     template<input_range _Range1, input_range _Range2>
       requires indirectly_swappable<iterator_t<_Range1>, iterator_t<_Range2>>
-      constexpr swap_ranges_result<safe_iterator_t<_Range1>,
-				   safe_iterator_t<_Range2>>
+      constexpr swap_ranges_result<borrowed_iterator_t<_Range1>,
+				   borrowed_iterator_t<_Range2>>
       operator()(_Range1&& __r1, _Range2&& __r2) const
       {
 	return (*this)(ranges::begin(__r1), ranges::end(__r1),
@@ -961,7 +961,7 @@ namespace ranges
       requires indirectly_writable<_Out,
 				   indirect_result_t<_Fp&,
 				     projected<iterator_t<_Range>, _Proj>>>
-      constexpr unary_transform_result<safe_iterator_t<_Range>, _Out>
+      constexpr unary_transform_result<borrowed_iterator_t<_Range>, _Out>
       operator()(_Range&& __r, _Out __result, _Fp __op, _Proj __proj = {}) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -998,8 +998,8 @@ namespace ranges
 				   indirect_result_t<_Fp&,
 				     projected<iterator_t<_Range1>, _Proj1>,
 				     projected<iterator_t<_Range2>, _Proj2>>>
-      constexpr binary_transform_result<safe_iterator_t<_Range1>,
-					safe_iterator_t<_Range2>, _Out>
+      constexpr binary_transform_result<borrowed_iterator_t<_Range1>,
+					borrowed_iterator_t<_Range2>, _Out>
       operator()(_Range1&& __r1, _Range2&& __r2, _Out __result, _Fp __binary_op,
 		 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
       {
@@ -1036,7 +1036,7 @@ namespace ranges
 	&& indirect_binary_predicate<ranges::equal_to,
 				     projected<iterator_t<_Range>, _Proj>,
 				     const _Tp1*>
-      constexpr safe_iterator_t<_Range>
+      constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r,
 		 const _Tp1& __old_value, const _Tp2& __new_value,
 		 _Proj __proj = {}) const
@@ -1068,7 +1068,7 @@ namespace ranges
 	     indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
 	       _Pred>
       requires indirectly_writable<iterator_t<_Range>, const _Tp&>
-      constexpr safe_iterator_t<_Range>
+      constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r,
 		 _Pred __pred, const _Tp& __new_value, _Proj __proj = {}) const
       {
@@ -1109,7 +1109,7 @@ namespace ranges
 	&& indirect_binary_predicate<ranges::equal_to,
 				     projected<iterator_t<_Range>, _Proj>,
 				     const _Tp1*>
-      constexpr replace_copy_result<safe_iterator_t<_Range>, _Out>
+      constexpr replace_copy_result<borrowed_iterator_t<_Range>, _Out>
       operator()(_Range&& __r, _Out __result,
 		 const _Tp1& __old_value, const _Tp2& __new_value,
 		 _Proj __proj = {}) const
@@ -1150,7 +1150,7 @@ namespace ranges
 	     indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
 	       _Pred>
       requires indirectly_copyable<iterator_t<_Range>, _Out>
-      constexpr replace_copy_if_result<safe_iterator_t<_Range>, _Out>
+      constexpr replace_copy_if_result<borrowed_iterator_t<_Range>, _Out>
       operator()(_Range&& __r, _Out __result,
 		 _Pred __pred, const _Tp& __new_value, _Proj __proj = {}) const
       {
@@ -1194,7 +1194,7 @@ namespace ranges
 
     template<typename _Range, copy_constructible _Fp>
       requires invocable<_Fp&> && output_range<_Range, invoke_result_t<_Fp&>>
-      constexpr safe_iterator_t<_Range>
+      constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r, _Fp __gen) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r), std::move(__gen));
@@ -1232,7 +1232,7 @@ namespace ranges
 	     indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
 	       _Pred>
       requires permutable<iterator_t<_Range>>
-      constexpr safe_subrange_t<_Range>
+      constexpr borrowed_subrange_t<_Range>
       operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -1265,7 +1265,7 @@ namespace ranges
 	&& indirect_binary_predicate<ranges::equal_to,
 				     projected<iterator_t<_Range>, _Proj>,
 				     const _Tp*>
-      constexpr safe_subrange_t<_Range>
+      constexpr borrowed_subrange_t<_Range>
       operator()(_Range&& __r, const _Tp& __value, _Proj __proj = {}) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -1302,7 +1302,7 @@ namespace ranges
 	     indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
 	       _Pred>
       requires indirectly_copyable<iterator_t<_Range>, _Out>
-      constexpr remove_copy_if_result<safe_iterator_t<_Range>, _Out>
+      constexpr remove_copy_if_result<borrowed_iterator_t<_Range>, _Out>
       operator()(_Range&& __r, _Out __result,
 		 _Pred __pred, _Proj __proj = {}) const
       {
@@ -1344,7 +1344,7 @@ namespace ranges
 	&& indirect_binary_predicate<ranges::equal_to,
 				     projected<iterator_t<_Range>, _Proj>,
 				     const _Tp*>
-      constexpr remove_copy_result<safe_iterator_t<_Range>, _Out>
+      constexpr remove_copy_result<borrowed_iterator_t<_Range>, _Out>
       operator()(_Range&& __r, _Out __result,
 		 const _Tp& __value, _Proj __proj = {}) const
       {
@@ -1383,7 +1383,7 @@ namespace ranges
 	     indirect_equivalence_relation<
 	       projected<iterator_t<_Range>, _Proj>> _Comp = ranges::equal_to>
       requires permutable<iterator_t<_Range>>
-      constexpr safe_subrange_t<_Range>
+      constexpr borrowed_subrange_t<_Range>
       operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -1467,7 +1467,7 @@ namespace ranges
 	    || (input_iterator<_Out>
 		&& same_as<range_value_t<_Range>, iter_value_t<_Out>>)
 	    || indirectly_copyable_storable<iterator_t<_Range>, _Out>)
-      constexpr unique_copy_result<safe_iterator_t<_Range>, _Out>
+      constexpr unique_copy_result<borrowed_iterator_t<_Range>, _Out>
       operator()(_Range&& __r, _Out __result,
 		 _Comp __comp = {}, _Proj __proj = {}) const
       {
@@ -1519,7 +1519,7 @@ namespace ranges
 
     template<bidirectional_range _Range>
       requires permutable<iterator_t<_Range>>
-      constexpr safe_iterator_t<_Range>
+      constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r));
@@ -1552,7 +1552,7 @@ namespace ranges
 
     template<bidirectional_range _Range, weakly_incrementable _Out>
       requires indirectly_copyable<iterator_t<_Range>, _Out>
-      constexpr reverse_copy_result<safe_iterator_t<_Range>, _Out>
+      constexpr reverse_copy_result<borrowed_iterator_t<_Range>, _Out>
       operator()(_Range&& __r, _Out __result) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -1699,7 +1699,7 @@ namespace ranges
 
     template<forward_range _Range>
       requires permutable<iterator_t<_Range>>
-      constexpr safe_subrange_t<_Range>
+      constexpr borrowed_subrange_t<_Range>
       operator()(_Range&& __r, iterator_t<_Range> __middle) const
       {
 	return (*this)(ranges::begin(__r), std::move(__middle),
@@ -1732,7 +1732,7 @@ namespace ranges
 
     template<forward_range _Range, weakly_incrementable _Out>
       requires indirectly_copyable<iterator_t<_Range>, _Out>
-      constexpr rotate_copy_result<safe_iterator_t<_Range>, _Out>
+      constexpr rotate_copy_result<borrowed_iterator_t<_Range>, _Out>
       operator()(_Range&& __r, iterator_t<_Range> __middle, _Out __result) const
       {
 	return (*this)(ranges::begin(__r), std::move(__middle),
@@ -1818,7 +1818,7 @@ namespace ranges
     template<random_access_range _Range, typename _Gen>
       requires permutable<iterator_t<_Range>>
 	&& uniform_random_bit_generator<remove_reference_t<_Gen>>
-      safe_iterator_t<_Range>
+      borrowed_iterator_t<_Range>
       operator()(_Range&& __r, _Gen&& __g) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -1847,7 +1847,7 @@ namespace ranges
     template<random_access_range _Range,
 	     typename _Comp = ranges::less, typename _Proj = identity>
       requires sortable<iterator_t<_Range>, _Comp, _Proj>
-      constexpr safe_iterator_t<_Range>
+      constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -1875,7 +1875,7 @@ namespace ranges
     template<random_access_range _Range,
 	     typename _Comp = ranges::less, typename _Proj = identity>
       requires sortable<iterator_t<_Range>, _Comp, _Proj>
-      constexpr safe_iterator_t<_Range>
+      constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -1903,7 +1903,7 @@ namespace ranges
     template<random_access_range _Range,
 	     typename _Comp = ranges::less, typename _Proj = identity>
       requires sortable<iterator_t<_Range>, _Comp, _Proj>
-      constexpr safe_iterator_t<_Range>
+      constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -1931,7 +1931,7 @@ namespace ranges
     template<random_access_range _Range,
 	     typename _Comp = ranges::less, typename _Proj = identity>
       requires sortable<iterator_t<_Range>, _Comp, _Proj>
-      constexpr safe_iterator_t<_Range>
+      constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -1968,7 +1968,7 @@ namespace ranges
 	     typename _Proj = identity,
 	     indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
 	       _Comp = ranges::less>
-      constexpr safe_iterator_t<_Range>
+      constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -2026,7 +2026,7 @@ namespace ranges
     template<random_access_range _Range,
 	     typename _Comp = ranges::less, typename _Proj = identity>
       requires sortable<iterator_t<_Range>, _Comp, _Proj>
-      constexpr safe_iterator_t<_Range>
+      constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -2054,7 +2054,7 @@ namespace ranges
     template<random_access_range _Range,
 	     typename _Comp = ranges::less, typename _Proj = identity>
       requires sortable<iterator_t<_Range>, _Comp, _Proj>
-      safe_iterator_t<_Range>
+      borrowed_iterator_t<_Range>
       operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -2095,7 +2095,7 @@ namespace ranges
     template<random_access_range _Range,
 	     typename _Comp = ranges::less, typename _Proj = identity>
       requires sortable<iterator_t<_Range>, _Comp, _Proj>
-      constexpr safe_iterator_t<_Range>
+      constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r, iterator_t<_Range> __middle,
 		 _Comp __comp = {}, _Proj __proj = {}) const
       {
@@ -2168,8 +2168,8 @@ namespace ranges
 	&& indirect_strict_weak_order<_Comp,
 				      projected<iterator_t<_Range1>, _Proj1>,
 				      projected<iterator_t<_Range2>, _Proj2>>
-      constexpr partial_sort_copy_result<safe_iterator_t<_Range1>,
-					 safe_iterator_t<_Range2>>
+      constexpr partial_sort_copy_result<borrowed_iterator_t<_Range1>,
+					 borrowed_iterator_t<_Range2>>
       operator()(_Range1&& __r, _Range2&& __out, _Comp __comp = {},
 		 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
       {
@@ -2207,7 +2207,7 @@ namespace ranges
     template<forward_range _Range, typename _Proj = identity,
 	     indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
 	       _Comp = ranges::less>
-      constexpr safe_iterator_t<_Range>
+      constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -2270,7 +2270,7 @@ namespace ranges
     template<random_access_range _Range,
 	     typename _Comp = ranges::less, typename _Proj = identity>
       requires sortable<iterator_t<_Range>, _Comp, _Proj>
-      constexpr safe_iterator_t<_Range>
+      constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r, iterator_t<_Range> __nth,
 		 _Comp __comp = {}, _Proj __proj = {}) const
       {
@@ -2314,7 +2314,7 @@ namespace ranges
 	     indirect_strict_weak_order<const _Tp*,
 					projected<iterator_t<_Range>, _Proj>>
 	       _Comp = ranges::less>
-      constexpr safe_iterator_t<_Range>
+      constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r,
 		 const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const
       {
@@ -2358,7 +2358,7 @@ namespace ranges
 	     indirect_strict_weak_order<const _Tp*,
 					projected<iterator_t<_Range>, _Proj>>
 	       _Comp = ranges::less>
-      constexpr safe_iterator_t<_Range>
+      constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r,
 		 const _Tp& __value, _Comp __comp = {}, _Proj __proj = {}) const
       {
@@ -2418,7 +2418,7 @@ namespace ranges
 	     indirect_strict_weak_order<const _Tp*,
 					projected<iterator_t<_Range>, _Proj>>
 	       _Comp = ranges::less>
-      constexpr safe_subrange_t<_Range>
+      constexpr borrowed_subrange_t<_Range>
       operator()(_Range&& __r, const _Tp& __value,
 		 _Comp __comp = {}, _Proj __proj = {}) const
       {
@@ -2554,7 +2554,7 @@ namespace ranges
 	     indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
 	       _Pred>
       requires permutable<iterator_t<_Range>>
-      constexpr safe_subrange_t<_Range>
+      constexpr borrowed_subrange_t<_Range>
       operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -2585,7 +2585,7 @@ namespace ranges
 	     indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
 	       _Pred>
       requires permutable<iterator_t<_Range>>
-      safe_subrange_t<_Range>
+      borrowed_subrange_t<_Range>
       operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -2658,7 +2658,7 @@ namespace ranges
 	       _Pred>
       requires indirectly_copyable<iterator_t<_Range>, _Out1>
 	&& indirectly_copyable<iterator_t<_Range>, _O2>
-      constexpr partition_copy_result<safe_iterator_t<_Range>, _Out1, _O2>
+      constexpr partition_copy_result<borrowed_iterator_t<_Range>, _Out1, _O2>
       operator()(_Range&& __r, _Out1 out_true, _O2 out_false,
 		 _Pred __pred, _Proj __proj = {}) const
       {
@@ -2701,7 +2701,7 @@ namespace ranges
     template<forward_range _Range, typename _Proj = identity,
 	     indirect_unary_predicate<projected<iterator_t<_Range>, _Proj>>
 	       _Pred>
-      constexpr safe_iterator_t<_Range>
+      constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r, _Pred __pred, _Proj __proj = {}) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -2756,8 +2756,8 @@ namespace ranges
 	     typename _Proj1 = identity, typename _Proj2 = identity>
       requires mergeable<iterator_t<_Range1>, iterator_t<_Range2>, _Out,
 			 _Comp, _Proj1, _Proj2>
-      constexpr merge_result<safe_iterator_t<_Range1>,
-			     safe_iterator_t<_Range2>,
+      constexpr merge_result<borrowed_iterator_t<_Range1>,
+			     borrowed_iterator_t<_Range2>,
 			     _Out>
       operator()(_Range1&& __r1, _Range2&& __r2, _Out __result,
 		 _Comp __comp = {},
@@ -2791,7 +2791,7 @@ namespace ranges
     template<bidirectional_range _Range,
 	     typename _Comp = ranges::less, typename _Proj = identity>
       requires sortable<iterator_t<_Range>, _Comp, _Proj>
-      safe_iterator_t<_Range>
+      borrowed_iterator_t<_Range>
       operator()(_Range&& __r, iterator_t<_Range> __middle,
 		 _Comp __comp = {}, _Proj __proj = {}) const
       {
@@ -2906,8 +2906,8 @@ namespace ranges
 	     typename _Proj1 = identity, typename _Proj2 = identity>
       requires mergeable<iterator_t<_Range1>, iterator_t<_Range2>, _Out,
 			 _Comp, _Proj1, _Proj2>
-      constexpr set_union_result<safe_iterator_t<_Range1>,
-				 safe_iterator_t<_Range2>, _Out>
+      constexpr set_union_result<borrowed_iterator_t<_Range1>,
+				 borrowed_iterator_t<_Range2>, _Out>
       operator()(_Range1&& __r1, _Range2&& __r2,
 		 _Out __result, _Comp __comp = {},
 		 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
@@ -2964,8 +2964,8 @@ namespace ranges
 	     typename _Proj1 = identity, typename _Proj2 = identity>
       requires mergeable<iterator_t<_Range1>, iterator_t<_Range2>, _Out,
 			 _Comp, _Proj1, _Proj2>
-      constexpr set_intersection_result<safe_iterator_t<_Range1>,
-					safe_iterator_t<_Range2>, _Out>
+      constexpr set_intersection_result<borrowed_iterator_t<_Range1>,
+					borrowed_iterator_t<_Range2>, _Out>
       operator()(_Range1&& __r1, _Range2&& __r2, _Out __result,
 		 _Comp __comp = {},
 		 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
@@ -3022,7 +3022,7 @@ namespace ranges
 	     typename _Proj1 = identity, typename _Proj2 = identity>
       requires mergeable<iterator_t<_Range1>, iterator_t<_Range2>, _Out,
 			 _Comp, _Proj1, _Proj2>
-      constexpr set_difference_result<safe_iterator_t<_Range1>, _Out>
+      constexpr set_difference_result<borrowed_iterator_t<_Range1>, _Out>
       operator()(_Range1&& __r1, _Range2&& __r2, _Out __result,
 		 _Comp __comp = {},
 		 _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const
@@ -3088,8 +3088,8 @@ namespace ranges
 	     typename _Proj1 = identity, typename _Proj2 = identity>
       requires mergeable<iterator_t<_Range1>, iterator_t<_Range2>, _Out,
 			 _Comp, _Proj1, _Proj2>
-      constexpr set_symmetric_difference_result<safe_iterator_t<_Range1>,
-						safe_iterator_t<_Range2>,
+      constexpr set_symmetric_difference_result<borrowed_iterator_t<_Range1>,
+						borrowed_iterator_t<_Range2>,
 						_Out>
       operator()(_Range1&& __r1, _Range2&& __r2, _Out __result,
 		 _Comp __comp = {},
@@ -3343,7 +3343,7 @@ namespace ranges
     template<forward_range _Range, typename _Proj = identity,
 	     indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
 	       _Comp = ranges::less>
-      constexpr safe_iterator_t<_Range>
+      constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -3380,7 +3380,7 @@ namespace ranges
     template<forward_range _Range, typename _Proj = identity,
 	     indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
 	       _Comp = ranges::less>
-      constexpr safe_iterator_t<_Range>
+      constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -3425,7 +3425,7 @@ namespace ranges
     template<forward_range _Range, typename _Proj = identity,
 	     indirect_strict_weak_order<projected<iterator_t<_Range>, _Proj>>
 	       _Comp = ranges::less>
-      constexpr minmax_element_result<safe_iterator_t<_Range>>
+      constexpr minmax_element_result<borrowed_iterator_t<_Range>>
       operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -3610,7 +3610,7 @@ namespace ranges
     template<bidirectional_range _Range, typename _Comp = ranges::less,
 	     typename _Proj = identity>
       requires sortable<iterator_t<_Range>, _Comp, _Proj>
-      constexpr next_permutation_result<safe_iterator_t<_Range>>
+      constexpr next_permutation_result<borrowed_iterator_t<_Range>>
       operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -3672,7 +3672,7 @@ namespace ranges
     template<bidirectional_range _Range, typename _Comp = ranges::less,
 	     typename _Proj = identity>
       requires sortable<iterator_t<_Range>, _Comp, _Proj>
-      constexpr prev_permutation_result<safe_iterator_t<_Range>>
+      constexpr prev_permutation_result<borrowed_iterator_t<_Range>>
       operator()(_Range&& __r, _Comp __comp = {}, _Proj __proj = {}) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r),
diff --git a/libstdc++-v3/include/bits/ranges_algobase.h b/libstdc++-v3/include/bits/ranges_algobase.h
index 7424766f053..807822e99c8 100644
--- a/libstdc++-v3/include/bits/ranges_algobase.h
+++ b/libstdc++-v3/include/bits/ranges_algobase.h
@@ -310,7 +310,7 @@ namespace ranges
 
     template<input_range _Range, weakly_incrementable _Out>
       requires indirectly_copyable<iterator_t<_Range>, _Out>
-      constexpr copy_result<safe_iterator_t<_Range>, _Out>
+      constexpr copy_result<borrowed_iterator_t<_Range>, _Out>
       operator()(_Range&& __r, _Out __result) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -335,7 +335,7 @@ namespace ranges
 
     template<input_range _Range, weakly_incrementable _Out>
       requires indirectly_movable<iterator_t<_Range>, _Out>
-      constexpr move_result<safe_iterator_t<_Range>, _Out>
+      constexpr move_result<borrowed_iterator_t<_Range>, _Out>
       operator()(_Range&& __r, _Out __result) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -452,7 +452,7 @@ namespace ranges
 
     template<bidirectional_range _Range, bidirectional_iterator _Iter>
       requires indirectly_copyable<iterator_t<_Range>, _Iter>
-      constexpr copy_backward_result<safe_iterator_t<_Range>, _Iter>
+      constexpr copy_backward_result<borrowed_iterator_t<_Range>, _Iter>
       operator()(_Range&& __r, _Iter __result) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -477,7 +477,7 @@ namespace ranges
 
     template<bidirectional_range _Range, bidirectional_iterator _Iter>
       requires indirectly_movable<iterator_t<_Range>, _Iter>
-      constexpr move_backward_result<safe_iterator_t<_Range>, _Iter>
+      constexpr move_backward_result<borrowed_iterator_t<_Range>, _Iter>
       operator()(_Range&& __r, _Iter __result) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r),
@@ -577,7 +577,7 @@ namespace ranges
       }
 
     template<typename _Tp, output_range<const _Tp&> _Range>
-      constexpr safe_iterator_t<_Range>
+      constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r, const _Tp& __value) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r), __value);
diff --git a/libstdc++-v3/include/bits/ranges_uninitialized.h b/libstdc++-v3/include/bits/ranges_uninitialized.h
index 881bf39d5f8..01e1cad646c 100644
--- a/libstdc++-v3/include/bits/ranges_uninitialized.h
+++ b/libstdc++-v3/include/bits/ranges_uninitialized.h
@@ -88,7 +88,7 @@ namespace ranges
 
     template<__detail::__nothrow_input_range _Range>
       requires destructible<range_value_t<_Range>>
-      constexpr safe_iterator_t<_Range>
+      constexpr borrowed_iterator_t<_Range>
       operator()(_Range&& __r) const noexcept;
   };
 
@@ -159,7 +159,7 @@ namespace ranges
 
     template<__detail::__nothrow_forward_range _Range>
       requires default_initializable<range_value_t<_Range>>
-      safe_iterator_t<_Range>
+      borrowed_iterator_t<_Range>
       operator()(_Range&& __r) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r));
@@ -217,7 +217,7 @@ namespace ranges
 
     template<__detail::__nothrow_forward_range _Range>
       requires default_initializable<range_value_t<_Range>>
-      safe_iterator_t<_Range>
+      borrowed_iterator_t<_Range>
       operator()(_Range&& __r) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r));
@@ -290,8 +290,8 @@ namespace ranges
     template<input_range _IRange, __detail::__nothrow_forward_range _ORange>
       requires constructible_from<range_value_t<_ORange>,
 				  range_reference_t<_IRange>>
-      uninitialized_copy_result<safe_iterator_t<_IRange>,
-				safe_iterator_t<_ORange>>
+      uninitialized_copy_result<borrowed_iterator_t<_IRange>,
+				borrowed_iterator_t<_ORange>>
       operator()(_IRange&& __inr, _ORange&& __outr) const
       {
 	return (*this)(ranges::begin(__inr), ranges::end(__inr),
@@ -377,8 +377,8 @@ namespace ranges
     template<input_range _IRange, __detail::__nothrow_forward_range _ORange>
       requires constructible_from<range_value_t<_ORange>,
 	       range_rvalue_reference_t<_IRange>>
-      uninitialized_move_result<safe_iterator_t<_IRange>,
-				safe_iterator_t<_ORange>>
+      uninitialized_move_result<borrowed_iterator_t<_IRange>,
+				borrowed_iterator_t<_ORange>>
       operator()(_IRange&& __inr, _ORange&& __outr) const
       {
 	return (*this)(ranges::begin(__inr), ranges::end(__inr),
@@ -450,7 +450,7 @@ namespace ranges
 
     template<__detail::__nothrow_forward_range _Range, typename _Tp>
       requires constructible_from<range_value_t<_Range>, const _Tp&>
-      safe_iterator_t<_Range>
+      borrowed_iterator_t<_Range>
       operator()(_Range&& __r, const _Tp& __x) const
       {
 	return (*this)(ranges::begin(__r), ranges::end(__r), __x);
@@ -531,7 +531,7 @@ namespace ranges
 
   template<__detail::__nothrow_input_range _Range>
     requires destructible<range_value_t<_Range>>
-    constexpr safe_iterator_t<_Range>
+    constexpr borrowed_iterator_t<_Range>
     __destroy_fn::operator()(_Range&& __r) const noexcept
     {
       return (*this)(ranges::begin(__r), ranges::end(__r));
diff --git a/libstdc++-v3/include/experimental/string_view b/libstdc++-v3/include/experimental/string_view
index 4d4615c94e7..439650154ae 100644
--- a/libstdc++-v3/include/experimental/string_view
+++ b/libstdc++-v3/include/experimental/string_view
@@ -694,11 +694,11 @@ namespace experimental
 #if __cpp_lib_concepts
   namespace ranges
   {
-    template<typename> extern inline const bool enable_safe_range;
-    // Opt-in to safe_range concept
+    template<typename> extern inline const bool enable_borrowed_range;
+    // Opt-in to borrowed_range concept
     template<typename _CharT, typename _Traits>
       inline constexpr bool
-	enable_safe_range<experimental::basic_string_view<_CharT, _Traits>>
+	enable_borrowed_range<experimental::basic_string_view<_CharT, _Traits>>
 	  = true;
   }
 #endif
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index 4e50206fb61..4bfda88c319 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -93,7 +93,7 @@ namespace ranges
   /// A range which can be safely converted to a view.
   template<typename _Tp>
     concept viewable_range = range<_Tp>
-      && (safe_range<_Tp> || view<remove_cvref_t<_Tp>>);
+      && (borrowed_range<_Tp> || view<remove_cvref_t<_Tp>>);
 
   namespace __detail
   {
@@ -294,7 +294,7 @@ namespace ranges
       }
 
       template<__detail::__not_same_as<subrange> _Rng>
-	requires safe_range<_Rng>
+	requires borrowed_range<_Rng>
 	  && convertible_to<iterator_t<_Rng>, _It>
 	  && convertible_to<sentinel_t<_Rng>, _Sent>
 	constexpr
@@ -305,7 +305,7 @@ namespace ranges
 	    _M_size._M_size = ranges::size(__r);
 	}
 
-      template<safe_range _Rng>
+      template<borrowed_range _Rng>
 	requires convertible_to<iterator_t<_Rng>, _It>
 	  && convertible_to<sentinel_t<_Rng>, _Sent>
 	constexpr
@@ -417,14 +417,14 @@ namespace ranges
       -> subrange<tuple_element_t<0, _Pr>, tuple_element_t<1, _Pr>,
 		  subrange_kind::sized>;
 
-  template<safe_range _Rng>
+  template<borrowed_range _Rng>
     subrange(_Rng&&)
       -> subrange<iterator_t<_Rng>, sentinel_t<_Rng>,
 		 (sized_range<_Rng>
 		  || sized_sentinel_for<sentinel_t<_Rng>, iterator_t<_Rng>>)
 		 ? subrange_kind::sized : subrange_kind::unsized>;
 
-  template<safe_range _Rng>
+  template<borrowed_range _Rng>
     subrange(_Rng&&,
 	     __detail::__make_unsigned_like_t<range_difference_t<_Rng>>)
       -> subrange<iterator_t<_Rng>, sentinel_t<_Rng>, subrange_kind::sized>;
@@ -454,7 +454,7 @@ namespace ranges
   template<input_or_output_iterator _It, sentinel_for<_It> _Sent,
 	   subrange_kind _Kind>
     inline constexpr bool
-      enable_safe_range<subrange<_It, _Sent, _Kind>> = true;
+      enable_borrowed_range<subrange<_It, _Sent, _Kind>> = true;
 
 } // namespace ranges
 
@@ -471,14 +471,14 @@ namespace ranges
   };
 
   template<range _Range>
-    using safe_iterator_t = conditional_t<safe_range<_Range>,
-					  iterator_t<_Range>,
-					  dangling>;
+    using borrowed_iterator_t = conditional_t<borrowed_range<_Range>,
+					      iterator_t<_Range>,
+					      dangling>;
 
   template<range _Range>
-    using safe_subrange_t = conditional_t<safe_range<_Range>,
-					  subrange<iterator_t<_Range>>,
-					  dangling>;
+    using borrowed_subrange_t = conditional_t<borrowed_range<_Range>,
+					      subrange<iterator_t<_Range>>,
+					      dangling>;
 
   template<typename _Tp> requires is_object_v<_Tp>
     class empty_view
@@ -493,7 +493,7 @@ namespace ranges
     };
 
   template<typename _Tp>
-    inline constexpr bool enable_safe_range<empty_view<_Tp>> = true;
+    inline constexpr bool enable_borrowed_range<empty_view<_Tp>> = true;
 
   namespace __detail
   {
@@ -919,7 +919,8 @@ namespace ranges
     iota_view(_Winc, _Bound) -> iota_view<_Winc, _Bound>;
 
   template<weakly_incrementable _Winc, semiregular _Bound>
-    inline constexpr bool enable_safe_range<iota_view<_Winc, _Bound>> = true;
+    inline constexpr bool
+      enable_borrowed_range<iota_view<_Winc, _Bound>> = true;
 
 namespace views
 {
@@ -1221,7 +1222,7 @@ namespace views
     ref_view(_Range&) -> ref_view<_Range>;
 
   template<typename _Tp>
-    inline constexpr bool enable_safe_range<ref_view<_Tp>> = true;
+    inline constexpr bool enable_borrowed_range<ref_view<_Tp>> = true;
 
   namespace views
   {
diff --git a/libstdc++-v3/include/std/span b/libstdc++-v3/include/std/span
index a8c69796e5e..63dc2515b25 100644
--- a/libstdc++-v3/include/std/span
+++ b/libstdc++-v3/include/std/span
@@ -207,7 +207,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       template<typename _Range>
 	requires ranges::contiguous_range<_Range> && ranges::sized_range<_Range>
-	  && (ranges::safe_range<_Range> || is_const_v<element_type>)
+	  && (ranges::borrowed_range<_Range> || is_const_v<element_type>)
 	  && (!__detail::__is_std_span<remove_cvref_t<_Range>>::value)
 	  && (!__detail::__is_std_array<remove_cvref_t<_Range>>::value)
 	  && (!is_array_v<remove_cvref_t<_Range>>)
@@ -465,11 +465,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   namespace ranges
   {
-    template<typename> extern inline const bool enable_safe_range;
-    // Opt-in to safe_range concept
+    template<typename> extern inline const bool enable_borrowed_range;
+    // Opt-in to borrowed_range concept
     template<typename _ElementType, size_t _Extent>
       inline constexpr bool
-	enable_safe_range<span<_ElementType, _Extent>> = true;
+	enable_borrowed_range<span<_ElementType, _Extent>> = true;
   }
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
diff --git a/libstdc++-v3/include/std/string_view b/libstdc++-v3/include/std/string_view
index bedad24979e..16687f6c352 100644
--- a/libstdc++-v3/include/std/string_view
+++ b/libstdc++-v3/include/std/string_view
@@ -727,11 +727,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #if __cpp_lib_concepts
   namespace ranges
   {
-    template<typename> extern inline const bool enable_safe_range;
-    // Opt-in to safe_range concept
+    template<typename> extern inline const bool enable_borrowed_range;
+    // Opt-in to borrowed_range concept
     template<typename _CharT, typename _Traits>
       inline constexpr bool
-	enable_safe_range<basic_string_view<_CharT, _Traits>> = true;
+	enable_borrowed_range<basic_string_view<_CharT, _Traits>> = true;
   }
 #endif
 _GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/testsuite/std/ranges/access/begin.cc b/libstdc++-v3/testsuite/std/ranges/access/begin.cc
index 882dffb4877..b6801552c60 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/begin.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/begin.cc
@@ -85,7 +85,7 @@ struct RV // view on an R
 };
 
 // Allow ranges::begin to work with RV&&
-template<> constexpr bool std::ranges::enable_safe_range<RV> = true;
+template<> constexpr bool std::ranges::enable_borrowed_range<RV> = true;
 
 void
 test03()
@@ -102,7 +102,7 @@ test03()
   VERIFY( std::ranges::begin(c) == begin(c) );
 
   RV v{r};
-  // enable_safe_range<RV> allows ranges::begin to work for rvalues,
+  // enable_borrowed_range<RV> allows ranges::begin to work for rvalues,
   // but it will call v.begin() or begin(v) on an lvalue:
   static_assert(same_as<decltype(std::ranges::begin(std::move(v))),
 		decltype(begin(v))>);
@@ -132,7 +132,7 @@ struct RR
 };
 
 // N.B. this is a lie, begin on an RR rvalue will return a dangling pointer.
-template<> constexpr bool std::ranges::enable_safe_range<RR> = true;
+template<> constexpr bool std::ranges::enable_borrowed_range<RR> = true;
 
 void
 test04()
diff --git a/libstdc++-v3/testsuite/std/ranges/access/cbegin.cc b/libstdc++-v3/testsuite/std/ranges/access/cbegin.cc
index 981f88d3b5d..6e994210c6b 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/cbegin.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/cbegin.cc
@@ -54,7 +54,7 @@ struct RV // view on an R
 };
 
 // Allow ranges::begin to work with RV&&
-template<> constexpr bool std::ranges::enable_safe_range<RV> = true;
+template<> constexpr bool std::ranges::enable_borrowed_range<RV> = true;
 
 void
 test03()
@@ -86,7 +86,7 @@ struct RR
 };
 
 // N.B. this is a lie, cbegin on an RR rvalue will return a dangling pointer.
-template<> constexpr bool std::ranges::enable_safe_range<RR> = true;
+template<> constexpr bool std::ranges::enable_borrowed_range<RR> = true;
 
 void
 test04()
diff --git a/libstdc++-v3/testsuite/std/ranges/access/cdata.cc b/libstdc++-v3/testsuite/std/ranges/access/cdata.cc
index c8489dd1ab9..8e68514bfad 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/cdata.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/cdata.cc
@@ -57,7 +57,7 @@ struct R
 };
 
 // This is a lie, ranges::begin(R&&) returns a dangling iterator.
-template<> constexpr bool std::ranges::enable_safe_range<R> = true;
+template<> constexpr bool std::ranges::enable_borrowed_range<R> = true;
 
 void
 test03()
diff --git a/libstdc++-v3/testsuite/std/ranges/access/cend.cc b/libstdc++-v3/testsuite/std/ranges/access/cend.cc
index 4172932118e..f3a00863a78 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/cend.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/cend.cc
@@ -60,7 +60,7 @@ struct RV // view on an R
 };
 
 // Allow ranges::end to work with RV&&
-template<> constexpr bool std::ranges::enable_safe_range<RV> = true;
+template<> constexpr bool std::ranges::enable_borrowed_range<RV> = true;
 
 void
 test03()
@@ -98,7 +98,7 @@ struct RR
 };
 
 // N.B. this is a lie, begin/end on an RR rvalue will return a dangling pointer.
-template<> constexpr bool std::ranges::enable_safe_range<RR> = true;
+template<> constexpr bool std::ranges::enable_borrowed_range<RR> = true;
 
 void
 test04()
diff --git a/libstdc++-v3/testsuite/std/ranges/access/crbegin.cc b/libstdc++-v3/testsuite/std/ranges/access/crbegin.cc
index 61724c8ba05..50d8eb43e75 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/crbegin.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/crbegin.cc
@@ -40,7 +40,7 @@ struct R1V // view on an R1
 };
 
 // Allow ranges::end to work with R1V&&
-template<> constexpr bool std::ranges::enable_safe_range<R1V> = true;
+template<> constexpr bool std::ranges::enable_borrowed_range<R1V> = true;
 
 void
 test01()
@@ -69,7 +69,7 @@ struct R2
 };
 
 // N.B. this is a lie, rbegin on an R2 rvalue will return a dangling pointer.
-template<> constexpr bool std::ranges::enable_safe_range<R2> = true;
+template<> constexpr bool std::ranges::enable_borrowed_range<R2> = true;
 
 void
 test02()
diff --git a/libstdc++-v3/testsuite/std/ranges/access/crend.cc b/libstdc++-v3/testsuite/std/ranges/access/crend.cc
index 85fecf1221c..4d50f4a0965 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/crend.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/crend.cc
@@ -34,7 +34,7 @@ struct R1
 };
 
 // N.B. this is a lie, rend on an R1 rvalue will return a dangling pointer.
-template<> constexpr bool std::ranges::enable_safe_range<R1> = true;
+template<> constexpr bool std::ranges::enable_borrowed_range<R1> = true;
 
 void
 test01()
@@ -60,7 +60,7 @@ struct R2
 };
 
 // N.B. this is a lie, rend on an R2 rvalue will return a dangling pointer.
-template<> constexpr bool std::ranges::enable_safe_range<R2> = true;
+template<> constexpr bool std::ranges::enable_borrowed_range<R2> = true;
 
 void
 test02()
@@ -85,7 +85,7 @@ struct R3
 };
 
 // N.B. this is a lie, rend on an R3 rvalue will return a dangling pointer.
-template<> constexpr bool std::ranges::enable_safe_range<R3> = true;
+template<> constexpr bool std::ranges::enable_borrowed_range<R3> = true;
 
 void
 test03()
diff --git a/libstdc++-v3/testsuite/std/ranges/access/data.cc b/libstdc++-v3/testsuite/std/ranges/access/data.cc
index b7f04929f92..bcd564b75c8 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/data.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/data.cc
@@ -61,7 +61,7 @@ struct R3
 };
 
 // N.B. this is a lie, begin on an R3 rvalue will return a dangling pointer.
-template<> constexpr bool std::ranges::enable_safe_range<R3> = true;
+template<> constexpr bool std::ranges::enable_borrowed_range<R3> = true;
 
 void
 test03()
@@ -69,7 +69,7 @@ test03()
   R3 r;
   const R3& c = r;
   // r.data() can only be used on an lvalue, but ranges::begin(R3&&) is OK
-  // because R3 satisfies ranges::safe_range.
+  // because R3 satisfies ranges::borrowed_range.
   VERIFY( std::ranges::data(std::move(r)) == std::to_address(std::ranges::begin(std::move(r))) );
   VERIFY( std::ranges::data(std::move(c)) == std::to_address(std::ranges::begin(std::move(c))) );
 }
diff --git a/libstdc++-v3/testsuite/std/ranges/access/end.cc b/libstdc++-v3/testsuite/std/ranges/access/end.cc
index c3a1028dc14..245f246c517 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/end.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/end.cc
@@ -90,7 +90,7 @@ struct RV // view on an R
 };
 
 // Allow ranges::begin to work with RV&&
-template<> constexpr bool std::ranges::enable_safe_range<RV> = true;
+template<> constexpr bool std::ranges::enable_borrowed_range<RV> = true;
 
 void
 test03()
@@ -146,7 +146,7 @@ struct RR
 };
 
 // N.B. this is a lie, end on an RR rvalue will return a dangling pointer.
-template<> constexpr bool std::ranges::enable_safe_range<RR> = true;
+template<> constexpr bool std::ranges::enable_borrowed_range<RR> = true;
 
 void
 test04()
diff --git a/libstdc++-v3/testsuite/std/ranges/access/rbegin.cc b/libstdc++-v3/testsuite/std/ranges/access/rbegin.cc
index e92e5bc69ac..bc49a10a734 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/rbegin.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/rbegin.cc
@@ -32,7 +32,7 @@ struct R1
 };
 
 // N.B. this is a lie, rbegin on an R1 rvalue will return a dangling pointer.
-template<> constexpr bool std::ranges::enable_safe_range<R1> = true;
+template<> constexpr bool std::ranges::enable_borrowed_range<R1> = true;
 
 void
 test01()
@@ -56,7 +56,7 @@ struct R2
 };
 
 // N.B. this is a lie, begin/end on an R2 rvalue will return a dangling pointer.
-template<> constexpr bool std::ranges::enable_safe_range<R2> = true;
+template<> constexpr bool std::ranges::enable_borrowed_range<R2> = true;
 
 void
 test02()
diff --git a/libstdc++-v3/testsuite/std/ranges/access/rend.cc b/libstdc++-v3/testsuite/std/ranges/access/rend.cc
index f6909b8340c..e80b5526f84 100644
--- a/libstdc++-v3/testsuite/std/ranges/access/rend.cc
+++ b/libstdc++-v3/testsuite/std/ranges/access/rend.cc
@@ -34,7 +34,7 @@ struct R1
 };
 
 // N.B. this is a lie, rend on an R1 rvalue will return a dangling pointer.
-template<> constexpr bool std::ranges::enable_safe_range<R1> = true;
+template<> constexpr bool std::ranges::enable_borrowed_range<R1> = true;
 
 void
 test01()
@@ -87,7 +87,7 @@ struct R3
 };
 
 // N.B. this is a lie, begin/end on an R3 rvalue will return a dangling pointer.
-template<> constexpr bool std::ranges::enable_safe_range<R3> = true;
+template<> constexpr bool std::ranges::enable_borrowed_range<R3> = true;
 
 void
 test03()
diff --git a/libstdc++-v3/testsuite/std/ranges/safe_range.cc b/libstdc++-v3/testsuite/std/ranges/safe_range.cc
index 6e50bf579c3..ec43f7884dc 100644
--- a/libstdc++-v3/testsuite/std/ranges/safe_range.cc
+++ b/libstdc++-v3/testsuite/std/ranges/safe_range.cc
@@ -21,21 +21,21 @@
 #include <ranges>
 #include <testsuite_iterators.h>
 
-static_assert( std::ranges::safe_range<int(&)[1]> );
-static_assert( std::ranges::safe_range<const int(&)[1]> );
-static_assert( !std::ranges::safe_range<int[1]> );
-static_assert( !std::ranges::safe_range<int*> );
+static_assert( std::ranges::borrowed_range<int(&)[1]> );
+static_assert( std::ranges::borrowed_range<const int(&)[1]> );
+static_assert( !std::ranges::borrowed_range<int[1]> );
+static_assert( !std::ranges::borrowed_range<int*> );
 
 using __gnu_test::test_contiguous_range;
 
-static_assert( !std::ranges::safe_range<test_contiguous_range<int>> );
-static_assert( std::ranges::safe_range<test_contiguous_range<int>&> );
-static_assert( !std::ranges::safe_range<test_contiguous_range<int>&&> );
+static_assert( !std::ranges::borrowed_range<test_contiguous_range<int>> );
+static_assert( std::ranges::borrowed_range<test_contiguous_range<int>&> );
+static_assert( !std::ranges::borrowed_range<test_contiguous_range<int>&&> );
 
 template<>
 constexpr bool
-  std::ranges::enable_safe_range<test_contiguous_range<long>> = true;
+  std::ranges::enable_borrowed_range<test_contiguous_range<long>> = true;
 
-static_assert( std::ranges::safe_range<test_contiguous_range<long>> );
-static_assert( std::ranges::safe_range<test_contiguous_range<long>&> );
-static_assert( std::ranges::safe_range<test_contiguous_range<long>&&> );
+static_assert( std::ranges::borrowed_range<test_contiguous_range<long>> );
+static_assert( std::ranges::borrowed_range<test_contiguous_range<long>&> );
+static_assert( std::ranges::borrowed_range<test_contiguous_range<long>&&> );
diff --git a/libstdc++-v3/testsuite/std/ranges/safe_range_types.cc b/libstdc++-v3/testsuite/std/ranges/safe_range_types.cc
index 3f0b52404a1..2835babfd82 100644
--- a/libstdc++-v3/testsuite/std/ranges/safe_range_types.cc
+++ b/libstdc++-v3/testsuite/std/ranges/safe_range_types.cc
@@ -25,35 +25,35 @@
 
 template<typename T>
 constexpr bool
-rvalue_is_safe_range()
+rvalue_is_borrowed_range()
 {
-  using std::ranges::safe_range;
+  using std::ranges::borrowed_range;
 
-  // An lvalue range always models safe_range
-  static_assert( safe_range<T&> );
-  static_assert( safe_range<const T&> );
+  // An lvalue range always models borrowed_range
+  static_assert( borrowed_range<T&> );
+  static_assert( borrowed_range<const T&> );
 
   // Result should not depend on addition of const or rvalue-reference.
-  static_assert( safe_range<T&&> == safe_range<T> );
-  static_assert( safe_range<const T> == safe_range<T> );
-  static_assert( safe_range<const T&&> == safe_range<T> );
+  static_assert( borrowed_range<T&&> == borrowed_range<T> );
+  static_assert( borrowed_range<const T> == borrowed_range<T> );
+  static_assert( borrowed_range<const T&&> == borrowed_range<T> );
 
-  return std::ranges::safe_range<T>;
+  return std::ranges::borrowed_range<T>;
 }
 
-static_assert( rvalue_is_safe_range<std::ranges::subrange<int*, int*>>() );
-static_assert( rvalue_is_safe_range<std::ranges::empty_view<int>>() );
-static_assert( rvalue_is_safe_range<std::ranges::iota_view<int>>() );
-static_assert( rvalue_is_safe_range<std::ranges::iota_view<int, int>>() );
+static_assert( rvalue_is_borrowed_range<std::ranges::subrange<int*, int*>>() );
+static_assert( rvalue_is_borrowed_range<std::ranges::empty_view<int>>() );
+static_assert( rvalue_is_borrowed_range<std::ranges::iota_view<int>>() );
+static_assert( rvalue_is_borrowed_range<std::ranges::iota_view<int, int>>() );
 
-static_assert( rvalue_is_safe_range<std::span<int>>() );
-static_assert( rvalue_is_safe_range<std::span<int, 99>>() );
+static_assert( rvalue_is_borrowed_range<std::span<int>>() );
+static_assert( rvalue_is_borrowed_range<std::span<int, 99>>() );
 
-static_assert( ! rvalue_is_safe_range<std::string>() );
-static_assert( ! rvalue_is_safe_range<std::wstring>() );
+static_assert( ! rvalue_is_borrowed_range<std::string>() );
+static_assert( ! rvalue_is_borrowed_range<std::wstring>() );
 
-static_assert( rvalue_is_safe_range<std::string_view>() );
-static_assert( rvalue_is_safe_range<std::wstring_view>() );
+static_assert( rvalue_is_borrowed_range<std::string_view>() );
+static_assert( rvalue_is_borrowed_range<std::wstring_view>() );
 
-static_assert( rvalue_is_safe_range<std::experimental::string_view>() );
-static_assert( rvalue_is_safe_range<std::experimental::wstring_view>() );
+static_assert( rvalue_is_borrowed_range<std::experimental::string_view>() );
+static_assert( rvalue_is_borrowed_range<std::experimental::wstring_view>() );
diff --git a/libstdc++-v3/testsuite/util/testsuite_iterators.h b/libstdc++-v3/testsuite/util/testsuite_iterators.h
index 6887d806a31..7b7093919b7 100644
--- a/libstdc++-v3/testsuite/util/testsuite_iterators.h
+++ b/libstdc++-v3/testsuite/util/testsuite_iterators.h
@@ -765,8 +765,8 @@ namespace __gnu_test
       = test_sized_range<T, output_iterator_wrapper>;
 
 // test_range and test_sized_range do not own their elements, so they model
-// std::ranges::safe_range.  This file does not define specializations of
-// std::ranges::enable_safe_range, so that individual tests can decide
+// std::ranges::borrowed_range.  This file does not define specializations of
+// std::ranges::enable_borrowed_range, so that individual tests can decide
 // whether or not to do so.
 // This is also true for test_container, although only when it has forward
 // iterators (because output_iterator_wrapper and input_iterator_wrapper are

commit fa89adaa979093936d8f148ef5496db05ad308e5
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Feb 19 11:37:54 2020 +0000

    libstdc++: tuple_element_t is also wrong for const subrange (LWG 3398)
    
            * include/std/ranges (tuple_element<0, const subrange<I, S, K>>)
            (tuple_element<1, const subrange<I, S, K>>): Add partial
            specializations (LWG 3398).
            * testsuite/std/ranges/subrange/tuple_like.cc: New test.

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index a8fcd7cb475..f69507d667f 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,10 @@
 2020-02-19  Jonathan Wakely  <jwakely@redhat.com>
 
+	* include/std/ranges (tuple_element<0, const subrange<I, S, K>>)
+	(tuple_element<1, const subrange<I, S, K>>): Add partial
+	specializations (LWG 3398).
+	* testsuite/std/ranges/subrange/tuple_like.cc: New test.
+
 	* include/bits/ranges_algo.h (__find_fn, __find_first_of_fn)
 	(__adjacent_find_fn, __remove_if_fn, __remove_copy_if_fn)
 	(__unique_fn, __unique_copy_fn): Remove redundant conversions to bool.
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index e0eb84748a2..4e50206fb61 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -3193,7 +3193,6 @@ namespace views
 	typename tuple_size<_Tp>::type;
 	requires _Nm < tuple_size_v<_Tp>;
 	typename tuple_element_t<_Nm, _Tp>;
-	// XXX: we applied P3323 here
 	{ std::get<_Nm>(__t) }
 	  -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
       };
@@ -3451,6 +3450,14 @@ namespace views
     struct tuple_element<1, ranges::subrange<_Iter, _Sent, _Kind>>
     { using type = _Sent; };
 
+  template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
+    struct tuple_element<0, const ranges::subrange<_Iter, _Sent, _Kind>>
+    { using type = _Iter; };
+
+  template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
+    struct tuple_element<1, const ranges::subrange<_Iter, _Sent, _Kind>>
+    { using type = _Sent; };
+
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 #endif // library concepts
diff --git a/libstdc++-v3/testsuite/std/ranges/subrange/tuple_like.cc b/libstdc++-v3/testsuite/std/ranges/subrange/tuple_like.cc
new file mode 100644
index 00000000000..a3020d21d29
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/ranges/subrange/tuple_like.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 <ranges>
+
+using S1 = std::ranges::subrange<int*>;
+using S2 = std::ranges::subrange<long*, void*>;
+
+static_assert( std::tuple_size_v<S1> == 2 );
+static_assert( std::tuple_size_v<S2> == 2 );
+
+static_assert( std::same_as<std::tuple_element_t<0, S1>, int*> );
+static_assert( std::same_as<std::tuple_element_t<1, S1>, int*> );
+// LWG 3398
+static_assert( std::same_as<std::tuple_element_t<0, const S1>, int*> );
+static_assert( std::same_as<std::tuple_element_t<1, const S1>, int*> );
+
+static_assert( std::same_as<std::tuple_element_t<0, S2>, long*> );
+static_assert( std::same_as<std::tuple_element_t<1, S2>, void*> );
+// LWG 3398
+static_assert( std::same_as<std::tuple_element_t<0, const S2>, long*> );
+static_assert( std::same_as<std::tuple_element_t<1, const S2>, void*> );
+
+S1 s1;
+static_assert( std::same_as<decltype(std::get<0>(s1)), int*> );
+static_assert( std::same_as<decltype(std::get<1>(s1)), int*> );
+const S1 c1;
+static_assert( std::same_as<decltype(std::get<0>(c1)), int*> );
+static_assert( std::same_as<decltype(std::get<1>(c1)), int*> );
+S2 s2;
+static_assert( std::same_as<decltype(std::get<0>(s2)), long*> );
+static_assert( std::same_as<decltype(std::get<1>(s2)), void*> );
+const S2 c2;
+static_assert( std::same_as<decltype(std::get<0>(c2)), long*> );
+static_assert( std::same_as<decltype(std::get<1>(c2)), void*> );

commit a45fb21a10f486f6596b648e2c64bd1c7d808f18
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Feb 19 10:40:24 2020 +0000

    libstdc++: Remove redundant bool casts in ranges algorithms
    
    Some of these casts were added by me the other day, but some were
    already present. I think they are all redundant following the
    introduction of the boolean-testable concept in P1964R2.
    
            * include/bits/ranges_algo.h (__find_fn, __find_first_of_fn)
            (__adjacent_find_fn, __remove_if_fn, __remove_copy_if_fn)
            (__unique_fn, __unique_copy_fn): Remove redundant conversions to bool.

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index b60f5c301b4..a8fcd7cb475 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,9 @@
+2020-02-19  Jonathan Wakely  <jwakely@redhat.com>
+
+	* include/bits/ranges_algo.h (__find_fn, __find_first_of_fn)
+	(__adjacent_find_fn, __remove_if_fn, __remove_copy_if_fn)
+	(__unique_fn, __unique_copy_fn): Remove redundant conversions to bool.
+
 2020-02-18  Patrick Palka  <ppalka@redhat.com>
 
 	P1983R0 Wording for GB301, US296, US292, US291, and US283
diff --git a/libstdc++-v3/include/bits/ranges_algo.h b/libstdc++-v3/include/bits/ranges_algo.h
index 31b1bf0d448..a69181e12cb 100644
--- a/libstdc++-v3/include/bits/ranges_algo.h
+++ b/libstdc++-v3/include/bits/ranges_algo.h
@@ -244,7 +244,7 @@ namespace ranges
 		 const _Tp& __value, _Proj __proj = {}) const
       {
 	while (__first != __last
-	    && !(bool)(std::__invoke(__proj, *__first) == __value))
+	    && !(std::__invoke(__proj, *__first) == __value))
 	  ++__first;
 	return __first;
       }
@@ -333,9 +333,9 @@ namespace ranges
       {
 	for (; __first1 != __last1; ++__first1)
 	  for (auto __iter = __first2; __iter != __last2; ++__iter)
-	    if ((bool)std::__invoke(__pred,
-				    std::__invoke(__proj1, *__first1),
-				    std::__invoke(__proj2, *__iter)))
+	    if (std::__invoke(__pred,
+			      std::__invoke(__proj1, *__first1),
+			      std::__invoke(__proj2, *__iter)))
 	      return __first1;
 	return __first1;
       }
@@ -730,9 +730,9 @@ namespace ranges
 	auto __next = __first;
 	for (; ++__next != __last; __first = __next)
 	  {
-	    if ((bool)std::__invoke(__pred,
-				    std::__invoke(__proj, *__first),
-				    std::__invoke(__proj, *__next)))
+	    if (std::__invoke(__pred,
+			      std::__invoke(__proj, *__first),
+			      std::__invoke(__proj, *__next)))
 	      return __first;
 	  }
 	return __next;
@@ -1219,7 +1219,7 @@ namespace ranges
 	auto __result = __first;
 	++__first;
 	for (; __first != __last; ++__first)
-	  if (!(bool)std::__invoke(__pred, std::__invoke(__proj, *__first)))
+	  if (!std::__invoke(__pred, std::__invoke(__proj, *__first)))
 	    {
 	      *__result = std::move(*__first);
 	      ++__result;
@@ -1289,7 +1289,7 @@ namespace ranges
 		 _Pred __pred, _Proj __proj = {}) const
       {
 	for (; __first != __last; ++__first)
-	  if (!(bool)std::__invoke(__pred, std::__invoke(__proj, *__first)))
+	  if (!std::__invoke(__pred, std::__invoke(__proj, *__first)))
 	    {
 	      *__result = *__first;
 	      ++__result;
@@ -1372,9 +1372,9 @@ namespace ranges
 	auto __dest = __first;
 	++__first;
 	while (++__first != __last)
-	  if (!(bool)std::__invoke(__comp,
-				   std::__invoke(__proj, *__dest),
-				   std::__invoke(__proj, *__first)))
+	  if (!std::__invoke(__comp,
+			     std::__invoke(__proj, *__dest),
+			     std::__invoke(__proj, *__first)))
 	    *++__dest = std::move(*__first);
 	return {++__dest, __first};
       }
@@ -1420,9 +1420,9 @@ namespace ranges
 	    auto __next = __first;
 	    *__result = *__next;
 	    while (++__next != __last)
-	      if (!(bool)std::__invoke(__comp,
-				       std::__invoke(__proj, *__first),
-				       std::__invoke(__proj, *__next)))
+	      if (!std::__invoke(__comp,
+				 std::__invoke(__proj, *__first),
+				 std::__invoke(__proj, *__next)))
 		{
 		  __first = __next;
 		  *++__result = *__first;
@@ -1434,9 +1434,9 @@ namespace ranges
 	  {
 	    *__result = *__first;
 	    while (++__first != __last)
-	      if (!(bool)std::__invoke(__comp,
-				       std::__invoke(__proj, *__result),
-				       std::__invoke(__proj, *__first)))
+	      if (!std::__invoke(__comp,
+				 std::__invoke(__proj, *__result),
+				 std::__invoke(__proj, *__first)))
 		  *++__result = *__first;
 	    return {std::move(__first), std::move(++__result)};
 	  }

commit 73d531205083eaf19934b516b37b1cf4940895c7
Author: Bernd Edlinger <bernd.edlinger@hotmail.de>
Date:   Mon Feb 17 17:40:07 2020 +0100

    Fix -save-temp leaking files in /tmp
    
    And avoid signal handler calling signal unsafe functions,
    and/or calling unlink with uninitialized memory pointer.
    
    2020-02-19  Bernd Edlinger  <bernd.edlinger@hotmail.de>
    
            * collect2.c (c_file, o_file): Make const again.
            (ldout,lderrout, dump_ld_file): Remove.
            (tool_cleanup): Avoid calling not signal-safe functions.
            (maybe_run_lto_and_relink): Avoid possible signal handler
            access to unintialzed memory (lto_o_files).
            (main): Avoid leaking temp files in $TMPDIR.
            Initialize c_file/o_file with concat, which avoids exposing
            uninitialized memory to signal handler, which calls unlink(!).
            Avoid calling maybe_unlink when the main function returns,
            since the atexit handler is already doing this.
            * collect2.h (dump_ld_file, ldout, lderrout): Remove.

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7ebeaed89e0..6cd941a5ff8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2020-02-19  Bernd Edlinger  <bernd.edlinger@hotmail.de>
+
+	* collect2.c (c_file, o_file): Make const again.
+	(ldout,lderrout, dump_ld_file): Remove.
+	(tool_cleanup): Avoid calling not signal-safe functions.
+	(maybe_run_lto_and_relink): Avoid possible signal handler
+	access to unintialzed memory (lto_o_files).
+	(main): Avoid leaking temp files in $TMPDIR.
+	Initialize c_file/o_file with concat, which avoids exposing
+	uninitialized memory to signal handler, which calls unlink(!).
+	Avoid calling maybe_unlink when the main function returns,
+	since the atexit handler is already doing this.
+	* collect2.h (dump_ld_file, ldout, lderrout): Remove.
+
 2020-02-19  Martin Jambor  <mjambor@suse.cz>
 
 	PR tree-optimization/93776
diff --git a/gcc/collect2.c b/gcc/collect2.c
index 502d629141c..f7d9f103ddc 100644
--- a/gcc/collect2.c
+++ b/gcc/collect2.c
@@ -205,14 +205,12 @@ bool helpflag;			/* true if --help */
 static int shared_obj;			/* true if -shared */
 static int static_obj;			/* true if -static */
 
-static char *c_file;		/* <xxx>.c for constructor/destructor list.  */
-static char *o_file;		/* <xxx>.o for constructor/destructor list.  */
+static const char *c_file;		/* <xxx>.c for constructor/destructor list.  */
+static const char *o_file;		/* <xxx>.o for constructor/destructor list.  */
 #ifdef COLLECT_EXPORT_LIST
 static const char *export_file;		/* <xxx>.x for AIX export list.  */
 #endif
 static char **lto_o_files;		/* Output files for LTO.  */
-const char *ldout;			/* File for ld stdout.  */
-const char *lderrout;			/* File for ld stderr.  */
 static const char *output_file;		/* Output file for ld.  */
 static const char *nm_file_name;	/* pathname of nm */
 #ifdef LDD_SUFFIX
@@ -384,6 +382,10 @@ static void scan_prog_file (const char *, scanpass, scanfilter);
 void
 tool_cleanup (bool from_signal)
 {
+  /* maybe_unlink may call notice, which is not signal safe.  */
+  if (from_signal)
+    verbose = false;
+
   if (c_file != 0 && c_file[0])
     maybe_unlink (c_file);
 
@@ -397,20 +399,6 @@ tool_cleanup (bool from_signal)
 
   if (lto_o_files)
     maybe_unlink_list (lto_o_files);
-
-  if (ldout != 0 && ldout[0])
-    {
-      if (!from_signal)
-	dump_ld_file (ldout, stdout);
-      maybe_unlink (ldout);
-    }
-
-  if (lderrout != 0 && lderrout[0])
-    {
-      if (!from_signal)
-	dump_ld_file (lderrout, stderr);
-      maybe_unlink (lderrout);
-    }
 }
 
 static void
@@ -476,77 +464,6 @@ extract_string (const char **pp)
   return XOBFINISH (&temporary_obstack, char *);
 }
 \f
-void
-dump_ld_file (const char *name, FILE *to)
-{
-  FILE *stream = fopen (name, "r");
-
-  if (stream == 0)
-    return;
-  while (1)
-    {
-      int c;
-      while (c = getc (stream),
-	     c != EOF && (ISIDNUM (c) || c == '$' || c == '.'))
-	obstack_1grow (&temporary_obstack, c);
-      if (obstack_object_size (&temporary_obstack) > 0)
-	{
-	  const char *word, *p;
-	  char *result;
-	  obstack_1grow (&temporary_obstack, '\0');
-	  word = XOBFINISH (&temporary_obstack, const char *);
-
-	  if (*word == '.')
-	    ++word, putc ('.', to);
-	  p = word;
-	  if (!strncmp (p, USER_LABEL_PREFIX, strlen (USER_LABEL_PREFIX)))
-	    p += strlen (USER_LABEL_PREFIX);
-
-#ifdef HAVE_LD_DEMANGLE
-	  result = 0;
-#else
-	  if (no_demangle)
-	    result = 0;
-	  else
-	    result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE);
-#endif
-
-	  if (result)
-	    {
-	      int diff;
-	      fputs (result, to);
-
-	      diff = strlen (word) - strlen (result);
-	      while (diff > 0 && c == ' ')
-		--diff, putc (' ', to);
-	      if (diff < 0 && c == ' ')
-		{
-		  while (diff < 0 && c == ' ')
-		    ++diff, c = getc (stream);
-		  if (!ISSPACE (c))
-		    {
-		      /* Make sure we output at least one space, or
-			 the demangled symbol name will run into
-			 whatever text follows.  */
-		      putc (' ', to);
-		    }
-		}
-
-	      free (result);
-	    }
-	  else
-	    fputs (word, to);
-
-	  fflush (to);
-	  obstack_free (&temporary_obstack, temporary_firstobj);
-	}
-      if (c == EOF)
-	break;
-      putc (c, to);
-    }
-  fclose (stream);
-}
-\f
 /* Return the kind of symbol denoted by name S.  */
 
 static symkind
@@ -744,7 +661,10 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst,
 	      ++num_files;
 	  }
 
-	lto_o_files = XNEWVEC (char *, num_files + 1);
+	/* signal handler may access uninitialized memory
+	   and delete whatever it points to, if lto_o_files
+	   is not allocatted with calloc.  */
+	lto_o_files = XCNEWVEC (char *, num_files + 1);
 	lto_o_files[num_files] = NULL;
 	start = XOBFINISH (&temporary_obstack, char *);
 	for (i = 0; i < num_files; ++i)
@@ -1262,27 +1182,19 @@ main (int argc, char **argv)
   /* Make temp file names.  */
   if (save_temps)
     {
-      c_file = (char *) xmalloc (strlen (output_file)
-				  + sizeof (".cdtor.c") + 1);
-      strcpy (c_file, output_file);
-      strcat (c_file, ".cdtor.c");
-      o_file = (char *) xmalloc (strlen (output_file)
-				  + sizeof (".cdtor.o") + 1);
-      strcpy (o_file, output_file);
-      strcat (o_file, ".cdtor.o");
+      c_file = concat (output_file, ".cdtor.c", NULL);
+      o_file = concat (output_file, ".cdtor.o", NULL);
+#ifdef COLLECT_EXPORT_LIST
+      export_file = concat (output_file, ".x", NULL);
+#endif
     }
   else
     {
       c_file = make_temp_file (".cdtor.c");
       o_file = make_temp_file (".cdtor.o");
-    }
 #ifdef COLLECT_EXPORT_LIST
-  export_file = make_temp_file (".x");
+      export_file = make_temp_file (".x");
 #endif
-  if (!debug)
-    {
-      ldout = make_temp_file (".ld");
-      lderrout = make_temp_file (".le");
     }
   /* Build the command line to compile the ctor/dtor list.  */
   *c_ptr++ = c_file_name;
@@ -1811,9 +1723,6 @@ main (int argc, char **argv)
       maybe_unlink (export_file);
 #endif
       post_ld_pass (/*temp_file*/false);
-
-      maybe_unlink (c_file);
-      maybe_unlink (o_file);
       return 0;
     }
 
@@ -1912,13 +1821,6 @@ main (int argc, char **argv)
   scan_prog_file (output_file, PASS_SECOND, SCAN_ALL);
 #endif
 
-  maybe_unlink (c_file);
-  maybe_unlink (o_file);
-
-#ifdef COLLECT_EXPORT_LIST
-  maybe_unlink (export_file);
-#endif
-
   return 0;
 }
 
diff --git a/gcc/collect2.h b/gcc/collect2.h
index ab5fcdf0ed8..aa8a03e7d87 100644
--- a/gcc/collect2.h
+++ b/gcc/collect2.h
@@ -25,12 +25,8 @@ extern struct pex_obj *collect_execute (const char *, char **, const char *,
 
 extern int collect_wait (const char *, struct pex_obj *);
 
-extern void dump_ld_file (const char *, FILE *);
-
 extern int file_exists (const char *);
 
-extern const char *ldout;
-extern const char *lderrout;
 extern const char *c_file_name;
 extern struct obstack temporary_obstack;
 extern char *temporary_firstobj;

commit 51faf07cef9293af544bfacc7d0b320ab90d7d60
Author: Martin Jambor <mjambor@suse.cz>
Date:   Wed Feb 19 11:13:52 2020 +0100

    sra: Do not create zero sized accesses  (PR 93776)
    
    SRA can get a bit confused with zero-sized accesses like the one in
    the testcase.  Since there is nothing in the access, nothing is
    scalarized, but we can get order of the structures wrong, which the
    verifier is not happy about.
    
    Fixed by simply ignoring such accesses.
    
    2020-02-19  Martin Jambor  <mjambor@suse.cz>
    
            PR tree-optimization/93776
            * tree-sra.c (create_access): Do not create zero size accesses.
            (get_access_for_expr): Do not search for zero sized accesses.
    
            testsuite/
            * gcc.dg/tree-ssa/pr93776.c: New test.

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6b53f9a2f07..7ebeaed89e0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2020-02-19  Martin Jambor  <mjambor@suse.cz>
+
+	PR tree-optimization/93776
+	* tree-sra.c (create_access): Do not create zero size accesses.
+	(get_access_for_expr): Do not search for zero sized accesses.
+
 2020-02-19  Martin Jambor  <mjambor@suse.cz>
 
 	PR tree-optimization/93667
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8033fa0a3bb..df79951b6cc 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2020-02-19  Martin Jambor  <mjambor@suse.cz>
+
+	PR tree-optimization/93776
+	* gcc.dg/tree-ssa/pr93776.c: New test.
+
 2020-02-19  Martin Jambor  <mjambor@suse.cz>
 
 	PR tree-optimization/93667
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr93776.c b/gcc/testsuite/gcc.dg/tree-ssa/pr93776.c
new file mode 100644
index 00000000000..c407a627718
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr93776.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+struct empty {};
+struct s { int i; };
+struct z
+{
+  int j;
+  struct empty e;
+  struct s s;
+  int k;
+};
+
+void bar (struct z);
+void baz (int);
+
+void foo (void)
+{
+  struct z z, z2;
+
+  z.k = 8;
+  z2.s.i = 1;
+  z = z2;
+  bar (z);
+  z.e = (struct empty) {};
+  baz (z.k);
+}
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 4c7d651e6b9..49f9001f7fb 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -926,6 +926,8 @@ create_access (tree expr, gimple *stmt, bool write)
       size = max_size;
       unscalarizable_region = true;
     }
+  if (size == 0)
+    return NULL;
   if (size < 0)
     {
       disqualify_candidate (base, "Encountered an unconstrained access.");
@@ -3643,7 +3645,8 @@ get_access_for_expr (tree expr)
 	return NULL;
     }
 
-  if (!bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
+  if (max_size == 0
+      || !bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
     return NULL;
 
   return get_var_base_offset_size_access (base, offset, max_size);

commit 665c5bad168ab63629b29ed2ce08ed042c088dc2
Author: Martin Jambor <mjambor@suse.cz>
Date:   Wed Feb 19 11:08:40 2020 +0100

    sra: Avoid totally scalarizing overallping field_decls (PR 93667)
    
    [[no_unique_address]] C++ attribute can cause two fields of a
    RECORD_TYPE overlap, which currently confuses the totally scalarizing
    code into creating invalid access tree.  For GCC 10, I'd like to
    simply disable total scalarization of types where this happens.
    
    For GCC 11 I'll write down a TODO item to enable total scalarization
    of cases like this where the problematic fields are basically empty -
    despite having a non-zero size - i.e. when they are just RECORD_TYPEs
    without any data fields.
    
    2020-02-19  Martin Jambor  <mjambor@suse.cz>
    
            gcc/
    
            PR tree-optimization/93667
            * tree-sra.c (scalarizable_type_p): Return false if record fields
            do not follow wach other.
    
            gcc/testsuite/
    
            PR tree-optimization/93667
            * g++.dg/tree-ssa/pr93667.C: New test.

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 77c2a9ad810..6b53f9a2f07 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2020-02-19  Martin Jambor  <mjambor@suse.cz>
+
+	PR tree-optimization/93667
+	* tree-sra.c (scalarizable_type_p): Return false if record fields
+	do not follow wach other.
+
 2020-01-21  Kito Cheng  <kito.cheng@sifive.com>
 
 	* config/riscv/riscv.c (riscv_output_move) Using fmv.x.w/fmv.w.x
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9b4fe11a6f6..8033fa0a3bb 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2020-02-19  Martin Jambor  <mjambor@suse.cz>
+
+	PR tree-optimization/93667
+	* g++.dg/tree-ssa/pr93667.C: New test.
+
 2020-02-19  Hongtao Liu  <hongtao.liu@intel.com>
 
 	* g++.dg/other/i386-2.C: add -mavx512vbmi2
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr93667.C b/gcc/testsuite/g++.dg/tree-ssa/pr93667.C
new file mode 100644
index 00000000000..d875f53d9ec
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr93667.C
@@ -0,0 +1,11 @@
+// { dg-do compile }
+// { dg-options "-O2 -std=c++2a" } */
+
+struct a {};
+struct b { [[no_unique_address]] a aq; };
+struct c {
+  int d;
+  [[no_unique_address]] b e;
+};
+c f() {return {};}
+void g() { f(); }
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 0cfac0a8192..4c7d651e6b9 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -958,6 +958,9 @@ scalarizable_type_p (tree type, bool const_decl)
   if (type_contains_placeholder_p (type))
     return false;
 
+  bool have_predecessor_field = false;
+  HOST_WIDE_INT prev_pos = 0;
+
   switch (TREE_CODE (type))
   {
   case RECORD_TYPE:
@@ -966,6 +969,17 @@ scalarizable_type_p (tree type, bool const_decl)
 	{
 	  tree ft = TREE_TYPE (fld);
 
+	  if (zerop (DECL_SIZE (fld)))
+	    continue;
+
+	  HOST_WIDE_INT pos = int_bit_position (fld);
+	  if (have_predecessor_field
+	      && pos <= prev_pos)
+	    return false;
+
+	  have_predecessor_field = true;
+	  prev_pos = pos;
+
 	  if (DECL_BIT_FIELD (fld))
 	    return false;
 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [committed] libstdc++: Implement LWG issues 3398, 3379, 3304, 3321, 3280, 3335
  2020-02-19 12:47 [committed] libstdc++: Implement LWG issues 3398, 3379, 3304, 3321, 3280, 3335 Jonathan Wakely
@ 2020-02-19 13:01 ` Jonathan Wakely
  2020-02-19 15:45 ` [committed] libstdc++: Implement LWG issues 3320, 3369, 3200, 3348, 3237 Jonathan Wakely
  1 sibling, 0 replies; 5+ messages in thread
From: Jonathan Wakely @ 2020-02-19 13:01 UTC (permalink / raw)
  To: libstdc++, gcc-patches

On 19/02/20 12:47 +0000, Jonathan Wakely wrote:
>Add ranges_size_t and rename all_view (LWG 3335)
>Remove converting constructors from views (LWG 3280)
>uninitialized_construct_using_allocator should use construct_at (LWG 3321)
>Add nodiscard to polymorphic_allocator members (LWG 3304)
>"safe" in several library names is misleading (LWG 3379)
>tuple_element_t is also wrong for const subrange (LWG 3398)
>
>Tested powerpc64le-linux, committed to master.

Oops, the attached patch also included three other commits that
weren't mine (but were already committed).


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [committed] libstdc++: Implement LWG issues 3320, 3369, 3200, 3348, 3237
  2020-02-19 12:47 [committed] libstdc++: Implement LWG issues 3398, 3379, 3304, 3321, 3280, 3335 Jonathan Wakely
  2020-02-19 13:01 ` Jonathan Wakely
@ 2020-02-19 15:45 ` Jonathan Wakely
  2020-02-19 21:22   ` [committed] libstdc++: Implement LWG issues 3247, 3282 Jonathan Wakely
  1 sibling, 1 reply; 5+ messages in thread
From: Jonathan Wakely @ 2020-02-19 15:45 UTC (permalink / raw)
  To: libstdc++, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 337 bytes --]

make polymorphic_allocator throw consistent type (LWG 3237)
Add __cpp_lib_unwrap_ref feature test macro
midpoint should not constrain T is complete (LWG 3200)
span's deduction-guide for built-in arrays doesn't work (LWG 3369)
Remove std::span::cbegin and std::span::cend (LWG 3320)

Tested powerpc64le-linux, committed to master.

[-- Attachment #2: patch.txt --]
[-- Type: text/x-patch, Size: 33264 bytes --]

commit e89100ef2efcf2bb1f1af1bdd81a1035d78f3fa4
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Feb 19 15:21:31 2020 +0000

    libstdc++: make polymorphic_allocator throw consistent type (LWG 3237)
    
            * include/std/memory_resource (polymorphic_allocator::allocate)
            (polymorphic_allocator::allocate_object): Change type of exception to
            bad_array_new_length (LWG 3237).
            * testsuite/20_util/polymorphic_allocator/lwg3237.cc: New test.

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index bc4ce773f1e..067cf8343f6 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,10 @@
 2020-02-19  Jonathan Wakely  <jwakely@redhat.com>
 
+	* include/std/memory_resource (polymorphic_allocator::allocate)
+	(polymorphic_allocator::allocate_object): Change type of exception to
+	bad_array_new_length (LWG 3237).
+	* testsuite/20_util/polymorphic_allocator/lwg3237.cc: New test.
+
 	* include/std/type_traits (__cpp_lib_unwrap_ref): Define (LWG 3348).
 	* include/std/version (__cpp_lib_unwrap_ref): Likewise.
 	* testsuite/20_util/unwrap_reference/1.cc: Check macro.
diff --git a/libstdc++-v3/include/std/memory_resource b/libstdc++-v3/include/std/memory_resource
index 73f77bdcadf..74683c5267f 100644
--- a/libstdc++-v3/include/std/memory_resource
+++ b/libstdc++-v3/include/std/memory_resource
@@ -167,7 +167,7 @@ namespace pmr
       __attribute__((__returns_nonnull__))
       {
 	if (__n > (__detail::__int_limits<size_t>::max() / sizeof(_Tp)))
-	  std::__throw_bad_alloc();
+	  _GLIBCXX_THROW_OR_ABORT(bad_array_new_length());
 	return static_cast<_Tp*>(_M_resource->allocate(__n * sizeof(_Tp),
 						       alignof(_Tp)));
       }
@@ -193,7 +193,7 @@ namespace pmr
 	allocate_object(size_t __n = 1)
 	{
 	  if ((__detail::__int_limits<size_t>::max() / sizeof(_Up)) < __n)
-	    __throw_length_error("polymorphic_allocator::allocate_object");
+	    _GLIBCXX_THROW_OR_ABORT(bad_array_new_length());
 	  return static_cast<_Up*>(allocate_bytes(__n * sizeof(_Up),
 						  alignof(_Up)));
 	}
diff --git a/libstdc++-v3/testsuite/20_util/polymorphic_allocator/lwg3237.cc b/libstdc++-v3/testsuite/20_util/polymorphic_allocator/lwg3237.cc
new file mode 100644
index 00000000000..350f5ac9c95
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/polymorphic_allocator/lwg3237.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 run { target c++2a } }
+
+#include <memory_resource>
+#include <testsuite_hooks.h>
+
+struct large { alignas(1024) int i; };
+
+void
+test01()
+{
+  std::pmr::polymorphic_allocator<large> a;
+  large* p = nullptr;
+  try
+  {
+    p = a.allocate(std::size_t(-1) / 256);
+    VERIFY( false );
+  }
+  catch (const std::bad_array_new_length&)
+  {
+  }
+
+  std::pmr::polymorphic_allocator<int> a2;
+  try
+  {
+    p = a2.allocate_object<large>(std::size_t(-1) / 256);
+    VERIFY( false );
+  }
+  catch (const std::bad_array_new_length&)
+  {
+  }
+}
+
+int
+main()
+{
+  test01();
+}

commit bb54e0b8794dfeea1f59ed9ca6433df1eccb85e9
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Feb 19 15:06:24 2020 +0000

    libstdc++: Add __cpp_lib_unwrap_ref feature test macro
    
    We already defined the traits in <type_traits> as now required by LWG
    3348, but the macro was missing. This adds it.
    
            * include/std/type_traits (__cpp_lib_unwrap_ref): Define (LWG 3348).
            * include/std/version (__cpp_lib_unwrap_ref): Likewise.
            * testsuite/20_util/unwrap_reference/1.cc: Check macro.
            * testsuite/20_util/unwrap_reference/3.cc: New test.

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 84e5ea98022..bc4ce773f1e 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,10 @@
 2020-02-19  Jonathan Wakely  <jwakely@redhat.com>
 
+	* include/std/type_traits (__cpp_lib_unwrap_ref): Define (LWG 3348).
+	* include/std/version (__cpp_lib_unwrap_ref): Likewise.
+	* testsuite/20_util/unwrap_reference/1.cc: Check macro.
+	* testsuite/20_util/unwrap_reference/3.cc: New test.
+
 	* include/std/numeric (midpoint(T8, T*)): Do not check for complete
 	type during overload resolution, use static assert instead (LWG 3200).
 	* testsuite/26_numerics/midpoint/pointer.cc: Do not test with
diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 684a792d02c..14aa2b37a4f 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -3242,6 +3242,8 @@ template <typename _From, typename _To>
   template<typename _Tp>
     using type_identity_t = typename type_identity<_Tp>::type;
 
+#define __cpp_lib_unwrap_ref 201811L
+
   /// Unwrap a reference_wrapper
   template<typename _Tp>
     struct unwrap_reference { using type = _Tp; };
diff --git a/libstdc++-v3/include/std/version b/libstdc++-v3/include/std/version
index b36b999cb31..e2ccf619d4a 100644
--- a/libstdc++-v3/include/std/version
+++ b/libstdc++-v3/include/std/version
@@ -178,6 +178,7 @@
 #ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
 # define __cpp_lib_is_constant_evaluated 201811L
 #endif
+#define __cpp_lib_unwrap_ref 201811L
 
 #if _GLIBCXX_HOSTED
 #define __cpp_lib_bind_front 201907L
diff --git a/libstdc++-v3/testsuite/20_util/unwrap_reference/1.cc b/libstdc++-v3/testsuite/20_util/unwrap_reference/1.cc
index 3a663433911..3496204e4d2 100644
--- a/libstdc++-v3/testsuite/20_util/unwrap_reference/1.cc
+++ b/libstdc++-v3/testsuite/20_util/unwrap_reference/1.cc
@@ -20,6 +20,12 @@
 
 #include <type_traits>
 
+#ifndef __cpp_lib_unwrap_ref
+# error "Feature-test macro for unwrap_reference missing in <type_traits>"
+#elif __cpp_lib_unwrap_ref != 201811L
+# error "Feature-test macro for unwrap_reference has wrong value in <type_traits>"
+#endif
+
 template<typename T, typename U> struct expect_same;
 template<typename T> struct expect_same<T, T> : std::true_type { };
 
diff --git a/libstdc++-v3/testsuite/20_util/unwrap_reference/3.cc b/libstdc++-v3/testsuite/20_util/unwrap_reference/3.cc
new file mode 100644
index 00000000000..3ea9cd18a05
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/unwrap_reference/3.cc
@@ -0,0 +1,27 @@
+// 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 <version>
+
+#ifndef __cpp_lib_unwrap_ref
+# error "Feature-test macro for unwrap_reference missing in <version>"
+#elif __cpp_lib_unwrap_ref != 201811L
+# error "Feature-test macro for unwrap_reference has wrong value in <version>"
+#endif

commit 5f031f9747fdfb04213c20d24f109fb5ffc877df
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Feb 19 15:01:41 2020 +0000

    libstdc++: midpoint should not constrain T is complete (LWG 3200)
    
            * include/std/numeric (midpoint(T8, T*)): Do not check for complete
            type during overload resolution, use static assert instead (LWG 3200).
            * testsuite/26_numerics/midpoint/pointer.cc: Do not test with
            incomplete type.
            * testsuite/26_numerics/midpoint/pointer_neg.cc: New test.

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 18085f3d9bd..84e5ea98022 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,11 @@
 2020-02-19  Jonathan Wakely  <jwakely@redhat.com>
 
+	* include/std/numeric (midpoint(T8, T*)): Do not check for complete
+	type during overload resolution, use static assert instead (LWG 3200).
+	* testsuite/26_numerics/midpoint/pointer.cc: Do not test with
+	incomplete type.
+	* testsuite/26_numerics/midpoint/pointer_neg.cc: New test.
+
 	* include/std/span (span(T (&)[N])): Use non-deduced context to
 	prevent first parameter from interfering with class template argument
 	deduction (LWG 3369).
diff --git a/libstdc++-v3/include/std/numeric b/libstdc++-v3/include/std/numeric
index 0b0a8ff8a61..cf35191cb47 100644
--- a/libstdc++-v3/include/std/numeric
+++ b/libstdc++-v3/include/std/numeric
@@ -208,10 +208,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
 
   template<typename _Tp>
-    constexpr
-    enable_if_t<__and_v<is_object<_Tp>, bool_constant<sizeof(_Tp) != 0>>, _Tp*>
+    constexpr enable_if_t<is_object_v<_Tp>, _Tp*>
     midpoint(_Tp* __a, _Tp* __b) noexcept
     {
+      static_assert( sizeof(_Tp) != 0, "type must be complete" );
       return __a  + (__b - __a) / 2;
     }
 _GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/testsuite/26_numerics/midpoint/pointer.cc b/libstdc++-v3/testsuite/26_numerics/midpoint/pointer.cc
index e0b75c92739..7e75d50663c 100644
--- a/libstdc++-v3/testsuite/26_numerics/midpoint/pointer.cc
+++ b/libstdc++-v3/testsuite/26_numerics/midpoint/pointer.cc
@@ -19,7 +19,6 @@
 // { dg-do run { target c++2a } }
 
 #include <numeric>
-#include <climits>
 #include <testsuite_hooks.h>
 
 const int* p = nullptr;
@@ -36,7 +35,6 @@ template<typename T> constexpr bool no_midpoint()
 static_assert(no_midpoint<void>());
 static_assert(no_midpoint<int()>());
 static_assert(no_midpoint<int&>());
-static_assert(no_midpoint<struct Incomplete>());
 
 constexpr int ca[3] = {};
 static_assert( std::midpoint(ca, ca+3) == ca+1 );
diff --git a/libstdc++-v3/testsuite/26_numerics/midpoint/pointer_neg.cc b/libstdc++-v3/testsuite/26_numerics/midpoint/pointer_neg.cc
new file mode 100644
index 00000000000..564b1acfe27
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/midpoint/pointer_neg.cc
@@ -0,0 +1,27 @@
+// 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 <numeric>
+
+// LWG 3200. midpoint should not constrain T is complete
+struct Incomplete* pinc = 0;
+auto p1 = std::midpoint(pinc, pinc); // { dg-error "here" }
+
+// { dg-error "incomplete type" "" { target *-*-* } 0 }

commit 66ae31eb308e5bc90ce6dfd0a67381a0929a6aa0
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Feb 19 14:41:46 2020 +0000

    libstdc++: span's deduction-guide for built-in arrays doesn't work (LWG 3369)
    
    The 23_containers/span/deduction.cc test was already passing, but only
    because I had previously implemented the original proposed resolution of
    3255. As pointed out in 3255 that original P/R was incorrect because it
    broke construction from array xvalues. This reverts the incorrect part
    of 3255 (and adds tests for the case it broke), and implements the
    resolution of 3369 instead.
    
            * include/std/span (span(T (&)[N])): Use non-deduced context to
            prevent first parameter from interfering with class template argument
            deduction (LWG 3369).
            * testsuite/23_containers/span/deduction.cc: Add missing 'const'.
            * testsuite/23_containers/span/lwg3255.cc: Check for construction from
            rvalues.

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index f5f8b6fd500..18085f3d9bd 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,12 @@
 2020-02-19  Jonathan Wakely  <jwakely@redhat.com>
 
+	* include/std/span (span(T (&)[N])): Use non-deduced context to
+	prevent first parameter from interfering with class template argument
+	deduction (LWG 3369).
+	* testsuite/23_containers/span/deduction.cc: Add missing 'const'.
+	* testsuite/23_containers/span/lwg3255.cc: Check for construction from
+	rvalues.
+
 	* include/std/span (span::const_iterator, span::const_reverse_iterator)
 	(span::cbegin(), span::cend(), span::crbegin(), span::crend()):
 	Remove (LWG 3320).
diff --git a/libstdc++-v3/include/std/span b/libstdc++-v3/include/std/span
index ccfd7db39fe..16b09a1e50c 100644
--- a/libstdc++-v3/include/std/span
+++ b/libstdc++-v3/include/std/span
@@ -182,10 +182,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	    }
 	}
 
-      template<typename _Tp, size_t _ArrayExtent>
-	requires __is_compatible_array<_Tp, _ArrayExtent>::value
+      template<size_t _ArrayExtent>
+	requires (_Extent == dynamic_extent || _ArrayExtent == _Extent)
 	constexpr
-	span(_Tp (&__arr)[_ArrayExtent]) noexcept
+	span(type_identity_t<element_type> (&__arr)[_ArrayExtent]) noexcept
 	: span(static_cast<pointer>(__arr), _ArrayExtent)
 	{ }
 
diff --git a/libstdc++-v3/testsuite/23_containers/span/deduction.cc b/libstdc++-v3/testsuite/23_containers/span/deduction.cc
index 66e955e961b..2fe1ac477c8 100644
--- a/libstdc++-v3/testsuite/23_containers/span/deduction.cc
+++ b/libstdc++-v3/testsuite/23_containers/span/deduction.cc
@@ -73,7 +73,7 @@ test01()
   std::span s9(s2);
   static_assert( is_static_span<int, 2>(s9) );
 
-  std::span s10(const_cast<std::span<int, 2>&>(s2));
+  std::span s10(const_cast<const std::span<int, 2>&>(s2));
   static_assert( is_static_span<int, 2>(s10) );
 
   std::span s11(s5);
diff --git a/libstdc++-v3/testsuite/23_containers/span/lwg3255.cc b/libstdc++-v3/testsuite/23_containers/span/lwg3255.cc
index 91edf6a04fd..03ced2c8710 100644
--- a/libstdc++-v3/testsuite/23_containers/span/lwg3255.cc
+++ b/libstdc++-v3/testsuite/23_containers/span/lwg3255.cc
@@ -57,10 +57,14 @@ static_assert( !is_constructible_v<span<const int, 1>, const array<const int, 2>
 static_assert( is_constructible_v<span<int>, int(&)[2]> );
 static_assert( is_constructible_v<span<const int>, int(&)[2]> );
 static_assert( is_constructible_v<span<const int>, const int(&)[2]> );
+static_assert( is_constructible_v<span<const int>, int[2]> );
+static_assert( is_constructible_v<span<const int>, const int[2]> );
 
 static_assert( is_constructible_v<span<int>, array<int, 2>&> );
 static_assert( is_constructible_v<span<const int>, array<int, 2>&> );
 static_assert( is_constructible_v<span<const int>, array<const int, 2>&> );
+static_assert( is_constructible_v<span<const int>, array<int, 2>> );
+static_assert( is_constructible_v<span<const int>, array<const int, 2>> );
 
 static_assert( is_constructible_v<span<const int>, const array<int, 2>&> );
 static_assert( is_constructible_v<span<const int>, const array<const int, 2>&> );

commit 247f410b83797a1840573840cc2a539ef9d7f96b
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Feb 19 14:00:59 2020 +0000

    libstdc++: Remove std::span::cbegin and std::span::cend (LWG 3320)
    
            * include/std/span (span::const_iterator, span::const_reverse_iterator)
            (span::cbegin(), span::cend(), span::crbegin(), span::crend()):
            Remove (LWG 3320).
            * testsuite/23_containers/span/everything.cc: Replace uses of cbegin
            and cend.
            * testsuite/20_util/specialized_algorithms/destroy/constrained.cc:
            Likewise.
            * testsuite/20_util/specialized_algorithms/uninitialized_copy/
            constrained.cc: Likewise.
            * testsuite/20_util/specialized_algorithms/
            uninitialized_default_construct/constrained.cc: Likewise.
            * testsuite/20_util/specialized_algorithms/uninitialized_fill/
            constrained.cc: Likewise.
            * testsuite/20_util/specialized_algorithms/uninitialized_move/
            constrained.cc: Likewise.
            * testsuite/20_util/specialized_algorithms/
            uninitialized_value_construct/constrained.cc: Likewise.

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index f01b78da118..f5f8b6fd500 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,23 @@
 2020-02-19  Jonathan Wakely  <jwakely@redhat.com>
 
+	* include/std/span (span::const_iterator, span::const_reverse_iterator)
+	(span::cbegin(), span::cend(), span::crbegin(), span::crend()):
+	Remove (LWG 3320).
+	* testsuite/23_containers/span/everything.cc: Replace uses of cbegin
+	and cend.
+	* testsuite/20_util/specialized_algorithms/destroy/constrained.cc:
+	Likewise.
+	* testsuite/20_util/specialized_algorithms/uninitialized_copy/
+	constrained.cc: Likewise.
+	* testsuite/20_util/specialized_algorithms/
+	uninitialized_default_construct/constrained.cc: Likewise.
+	* testsuite/20_util/specialized_algorithms/uninitialized_fill/
+	constrained.cc: Likewise.
+	* testsuite/20_util/specialized_algorithms/uninitialized_move/
+	constrained.cc: Likewise.
+	* testsuite/20_util/specialized_algorithms/
+	uninitialized_value_construct/constrained.cc: Likewise.
+
 	* include/bits/range_access.h (range_size_t): Define alias template.
 	* include/std/ranges (all_view): Rename to views::all_t (LWG 3335).
 	* testsuite/std/ranges/adaptors/filter.cc: Adjust to new name.
diff --git a/libstdc++-v3/include/std/span b/libstdc++-v3/include/std/span
index 63dc2515b25..ccfd7db39fe 100644
--- a/libstdc++-v3/include/std/span
+++ b/libstdc++-v3/include/std/span
@@ -141,9 +141,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       using reference              = element_type&;
       using const_reference        = const element_type&;
       using iterator = __gnu_cxx::__normal_iterator<pointer, span>;
-      using const_iterator = __gnu_cxx::__normal_iterator<const_pointer, span>;
       using reverse_iterator       = std::reverse_iterator<iterator>;
-      using const_reverse_iterator = std::reverse_iterator<const_iterator>;
 
       // member constants
       static constexpr size_t extent = _Extent;
@@ -297,34 +295,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       begin() const noexcept
       { return iterator(this->_M_ptr); }
 
-      constexpr const_iterator
-      cbegin() const noexcept
-      { return const_iterator(this->_M_ptr); }
-
       constexpr iterator
       end() const noexcept
       { return iterator(this->_M_ptr + this->size()); }
 
-      constexpr const_iterator
-      cend() const noexcept
-      { return const_iterator(this->_M_ptr + this->size()); }
-
       constexpr reverse_iterator
       rbegin() const noexcept
       { return reverse_iterator(this->end()); }
 
-      constexpr const_reverse_iterator
-      crbegin() const noexcept
-      { return const_reverse_iterator(this->cend()); }
-
       constexpr reverse_iterator
       rend() const noexcept
       { return reverse_iterator(this->begin()); }
 
-      constexpr const_reverse_iterator
-      crend() const noexcept
-      { return const_reverse_iterator(this->cbegin()); }
-
       // subviews
 
       template<size_t _Count>
diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/destroy/constrained.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/destroy/constrained.cc
index 730625d9a21..c04049de0b5 100644
--- a/libstdc++-v3/testsuite/20_util/specialized_algorithms/destroy/constrained.cc
+++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/destroy/constrained.cc
@@ -54,7 +54,7 @@ test01()
       ranges::uninitialized_default_construct(rx);
       VERIFY( X::count == size );
 
-      auto i = rx.cbegin();
+      auto i = rx.begin();
       if (k == 0)
 	i = ranges::destroy(rx);
       else if (k == 1)
@@ -64,7 +64,7 @@ test01()
       else
 	__builtin_abort();
 
-      VERIFY( i == rx.cend() );
+      VERIFY( i == rx.end() );
       VERIFY( X::count == 0 );
     }
 }
diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/constrained.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/constrained.cc
index 948406432cb..c1a50c45df9 100644
--- a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/constrained.cc
+++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_copy/constrained.cc
@@ -47,7 +47,7 @@ test01(const std::vector<T> &ix)
       auto buffer = std::unique_ptr<char[]>(new char[sizeof(T)*size]);
       std::span<T> rx((T *)buffer.get(), size);
 
-      ranges::uninitialized_copy_result res = {ix.cbegin(), rx.cbegin()};
+      ranges::uninitialized_copy_result res = {ix.begin(), rx.begin()};
       if (k == 0)
 	res = ranges::uninitialized_copy(ix.begin(), ix.end(),
 					 rx.begin(), rx.end());
@@ -58,33 +58,33 @@ test01(const std::vector<T> &ix)
 					   rx.begin(), rx.end());
       else if (k == 3)
 	res = ranges::uninitialized_copy(ix.begin(), ix.end(),
-					 rx.cbegin(), rx.cend());
+					 rx.begin(), rx.end());
       else if (k == 4)
 	res = ranges::uninitialized_copy(ix, std::as_const(rx));
       else if (k == 5)
 	res = ranges::uninitialized_copy_n(ix.begin(), size,
-					   rx.cbegin(), rx.cend());
+					   rx.begin(), rx.end());
       else if (k == 6)
 	res = ranges::uninitialized_copy_n(ix.begin(), size/2,
-					   rx.cbegin(), rx.cend());
+					   rx.begin(), rx.end());
       else if (k == 7)
 	res = ranges::uninitialized_copy_n(ix.begin(), size,
-					   rx.cbegin(), rx.cbegin()+size/2);
+					   rx.begin(), rx.begin()+size/2);
       else
 	__builtin_abort();
 
       if (k == 6 || k == 7)
 	{
-	  VERIFY( ranges::distance(ix.cbegin(), res.in) == size/2 );
-	  VERIFY( ranges::distance(rx.cbegin(), res.out) == size/2 );
+	  VERIFY( ranges::distance(ix.begin(), res.in) == size/2 );
+	  VERIFY( ranges::distance(rx.begin(), res.out) == size/2 );
 	  VERIFY( ranges::equal(ix.begin(), ix.begin()+size/2,
 				rx.begin(), rx.begin()+size/2) );
 	  ranges::destroy(rx.begin(), rx.begin()+size/2);
 	}
       else
 	{
-	  VERIFY( res.in == ix.cend() );
-	  VERIFY( res.out == rx.cend() );
+	  VERIFY( res.in == ix.end() );
+	  VERIFY( res.out == rx.end() );
 	  VERIFY( ranges::equal(ix, rx) );
 	  ranges::destroy(rx);
 	}
diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_default_construct/constrained.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_default_construct/constrained.cc
index 6ef24cc7ea0..d6ccfc7c7e4 100644
--- a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_default_construct/constrained.cc
+++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_default_construct/constrained.cc
@@ -53,7 +53,7 @@ test01()
 	  ranges::fill(rx, t);
 	}
 
-      auto i = rx.cbegin();
+      auto i = rx.begin();
       if (k == 0)
 	i = ranges::uninitialized_default_construct(rx.begin(), rx.end());
       else if (k == 1)
@@ -63,15 +63,15 @@ test01()
       else if constexpr (std::is_fundamental_v<T>)
 	continue;
       else if (k == 3)
-	i = ranges::uninitialized_default_construct(rx.cbegin(), rx.cend());
+	i = ranges::uninitialized_default_construct(rx.begin(), rx.end());
       else if (k == 4)
 	i = ranges::uninitialized_default_construct(std::as_const(rx));
       else if (k == 5)
-	i = ranges::uninitialized_default_construct_n(rx.cbegin(), 1024);
+	i = ranges::uninitialized_default_construct_n(rx.begin(), 1024);
       else
 	__builtin_abort();
 
-      VERIFY( i == rx.cend() );
+      VERIFY( i == rx.end() );
       VERIFY( ranges::find_if(rx, [&t](const T& v) { return t != v; }) == i );
 
       ranges::destroy(rx);
diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill/constrained.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill/constrained.cc
index c95fd666942..0fbbd1fa49f 100644
--- a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill/constrained.cc
+++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_fill/constrained.cc
@@ -45,7 +45,7 @@ test01(const T& value)
       auto buffer = std::unique_ptr<char[]>(new char[sizeof(T)*size]);
       std::span<T> rx((T *)buffer.get(), size);
 
-      auto i = rx.cbegin();
+      auto i = rx.begin();
       if (k == 0)
 	i = ranges::uninitialized_fill(rx.begin(), rx.end(), value);
       else if (k == 1)
@@ -53,15 +53,15 @@ test01(const T& value)
       else if (k == 2)
 	i = ranges::uninitialized_fill_n(rx.begin(), 1024, value);
       else if (k == 3)
-	i = ranges::uninitialized_fill(rx.cbegin(), rx.cend(), value);
+	i = ranges::uninitialized_fill(rx.begin(), rx.end(), value);
       else if (k == 4)
 	i = ranges::uninitialized_fill(std::as_const(rx), value);
       else if (k == 5)
-	i = ranges::uninitialized_fill_n(rx.cbegin(), 1024, value);
+	i = ranges::uninitialized_fill_n(rx.begin(), 1024, value);
       else
 	__builtin_abort();
 
-      VERIFY( i == rx.cend() );
+      VERIFY( i == rx.end() );
       VERIFY( ranges::find_if(rx, [&value](const T& v) { return value != v; }) == i );
 
       ranges::destroy(rx);
diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_move/constrained.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_move/constrained.cc
index 796c7ca8f46..a7d6fd39b38 100644
--- a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_move/constrained.cc
+++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_move/constrained.cc
@@ -51,7 +51,7 @@ test01(std::vector<T> ix)
       auto buffer = std::unique_ptr<char[]>(new char[sizeof(T)*size]);
       std::span<T> rx((T *)buffer.get(), size);
 
-      ranges::uninitialized_move_result res = {ix.cbegin(), rx.cbegin()};
+      ranges::uninitialized_move_result res = {ix.begin(), rx.begin()};
       if (k == 0)
 	res = ranges::uninitialized_move(ix.begin(), ix.end(),
 					 rx.begin(), rx.end());
@@ -62,33 +62,33 @@ test01(std::vector<T> ix)
 					   rx.begin(), rx.end());
       else if (k == 3)
 	res = ranges::uninitialized_move(ix.begin(), ix.end(),
-					 rx.cbegin(), rx.cend());
+					 rx.begin(), rx.end());
       else if (k == 4)
 	res = ranges::uninitialized_move(ix, std::as_const(rx));
       else if (k == 5)
 	res = ranges::uninitialized_move_n(ix.begin(), size,
-					   rx.cbegin(), rx.cend());
+					   rx.begin(), rx.end());
       else if (k == 6)
 	res = ranges::uninitialized_move_n(ix.begin(), size/2,
-					   rx.cbegin(), rx.cend());
+					   rx.begin(), rx.end());
       else if (k == 7)
 	res = ranges::uninitialized_move_n(ix.begin(), size,
-					   rx.cbegin(), rx.cbegin()+size/2);
+					   rx.begin(), rx.begin()+size/2);
       else
 	__builtin_abort();
 
       if (k == 6 || k == 7)
 	{
-	  VERIFY( ranges::distance(ix.cbegin(), res.in) == size/2 );
-	  VERIFY( ranges::distance(rx.cbegin(), res.out) == size/2 );
+	  VERIFY( ranges::distance(ix.begin(), res.in) == size/2 );
+	  VERIFY( ranges::distance(rx.begin(), res.out) == size/2 );
 	  VERIFY( ranges::equal(saved_ix.begin(), saved_ix.begin()+size/2,
 				rx.begin(), rx.begin()+size/2) );
 	  ranges::destroy(rx.begin(), rx.begin()+size/2);
 	}
       else
 	{
-	  VERIFY( res.in == ix.cend() );
-	  VERIFY( res.out == rx.cend() );
+	  VERIFY( res.in == ix.end() );
+	  VERIFY( res.out == rx.end() );
 	  VERIFY( ranges::equal(saved_ix, rx) );
 	  ranges::destroy(rx);
 	}
diff --git a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_value_construct/constrained.cc b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_value_construct/constrained.cc
index 5928bc04c70..ba3799b103e 100644
--- a/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_value_construct/constrained.cc
+++ b/libstdc++-v3/testsuite/20_util/specialized_algorithms/uninitialized_value_construct/constrained.cc
@@ -48,7 +48,7 @@ test01()
 
       T t{};
 
-      auto i = rx.cbegin();
+      auto i = rx.begin();
       if (k == 0)
 	i = ranges::uninitialized_value_construct(rx.begin(), rx.end());
       else if (k == 1)
@@ -56,15 +56,15 @@ test01()
       else if (k == 2)
 	i = ranges::uninitialized_value_construct_n(rx.begin(), 1024);
       else if (k == 3)
-	i = ranges::uninitialized_value_construct(rx.cbegin(), rx.cend());
+	i = ranges::uninitialized_value_construct(rx.begin(), rx.end());
       else if (k == 4)
 	i = ranges::uninitialized_value_construct(std::as_const(rx));
       else if (k == 5)
-	i = ranges::uninitialized_value_construct_n(rx.cbegin(), 1024);
+	i = ranges::uninitialized_value_construct_n(rx.begin(), 1024);
       else
 	__builtin_abort();
 
-      VERIFY( i == rx.cend() );
+      VERIFY( i == rx.end() );
       VERIFY( ranges::find_if(rx, [&t](const T& v) { return t != v; }) == i );
 
       ranges::destroy(rx);
diff --git a/libstdc++-v3/testsuite/23_containers/span/everything.cc b/libstdc++-v3/testsuite/23_containers/span/everything.cc
index 0cca06fa4fe..0ae4d741d0e 100644
--- a/libstdc++-v3/testsuite/23_containers/span/everything.cc
+++ b/libstdc++-v3/testsuite/23_containers/span/everything.cc
@@ -162,9 +162,8 @@ main()
   bool really_empty1 = std::empty(shorts);
   bool really_empty2 = shorts.data() == nullptr;
   bool really_empty3 = shorts.begin() == shorts.end();
-  bool really_empty4 = shorts.cbegin() == shorts.cend();
   bool really_empty =
-    really_empty0 && really_empty1 && really_empty2 && really_empty3 && really_empty4;
+    really_empty0 && really_empty1 && really_empty2 && really_empty3;
   (void)really_empty;
   VERIFY(really_empty);
 
@@ -179,10 +178,10 @@ main()
   std::span<const std::byte> muh_byte_span   = std::as_bytes(muh_span);
   std::span<std::byte> muh_mutable_byte_span = std::as_writable_bytes(muh_span);
   std::span<std::byte> muh_original_byte_span(original_bytes, original_bytes + 4);
-  bool definitely_reinterpret_casted0 = std::equal(muh_byte_span.cbegin(), muh_byte_span.cend(),
-    muh_original_byte_span.cbegin(), muh_original_byte_span.cend());
-  bool definitely_reinterpret_casted1 = std::equal(muh_mutable_byte_span.cbegin(),
-    muh_mutable_byte_span.cend(), muh_original_byte_span.cbegin(), muh_original_byte_span.cend());
+  bool definitely_reinterpret_casted0 = std::equal(muh_byte_span.begin(), muh_byte_span.end(),
+    muh_original_byte_span.begin(), muh_original_byte_span.end());
+  bool definitely_reinterpret_casted1 = std::equal(muh_mutable_byte_span.begin(),
+    muh_mutable_byte_span.end(), muh_original_byte_span.begin(), muh_original_byte_span.end());
   bool definitely_reinterpret_casted =
     definitely_reinterpret_casted0 && definitely_reinterpret_casted1;
   (void)definitely_reinterpret_casted;
@@ -190,8 +189,8 @@ main()
 
   std::span<std::byte> muh_original_byte_span_ptr_size(original_bytes, 4);
   bool definitely_equivalent =
-    std::equal(muh_original_byte_span_ptr_size.cbegin(), muh_original_byte_span_ptr_size.cend(),
-      muh_original_byte_span.cbegin(), muh_original_byte_span.cend());
+    std::equal(muh_original_byte_span_ptr_size.begin(), muh_original_byte_span_ptr_size.end(),
+      muh_original_byte_span.begin(), muh_original_byte_span.end());
   (void)definitely_equivalent;
   VERIFY(definitely_equivalent);
 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [committed] libstdc++: Implement LWG issues 3247, 3282
  2020-02-19 15:45 ` [committed] libstdc++: Implement LWG issues 3320, 3369, 3200, 3348, 3237 Jonathan Wakely
@ 2020-02-19 21:22   ` Jonathan Wakely
  2020-02-19 22:13     ` [committed] libstdc++: Implement LWG issues 3329, 3331, 3360, 3364, 3385 Jonathan Wakely
  0 siblings, 1 reply; 5+ messages in thread
From: Jonathan Wakely @ 2020-02-19 21:22 UTC (permalink / raw)
  To: libstdc++, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 183 bytes --]

subrange converting constructor should disallow slicing (LWG 3282)
ranges::iter_move should perform ADL-only lookup (LWG 3247)

Tested powerpc64le-linux, committed to master.



[-- Attachment #2: patch.txt --]
[-- Type: text/x-patch, Size: 8536 bytes --]

commit 77f5310f0205714538668b88fbf1de44f1f435be
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Feb 19 17:04:07 2020 +0000

    libstdc++: subrange converting constructor should disallow slicing (LWG 3282)
    
            * include/std/ranges (__detail::__convertible_to_non_slicing): New
            helper concept.
            (__detail::__pair_like_convertible_to): Remove.
            (__detail::__pair_like_convertible_from): Add requirements for
            non-slicing conversions.
            (subrange): Constrain constructors with __convertible_to_non_slicing.
            Remove constructors from pair-like types. Add new deduction guide.
            * testsuite/std/ranges/subrange/lwg3282_neg.cc: New test.

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 689bee8c2a9..6e22536680f 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,14 @@
 2020-02-19  Jonathan Wakely  <jwakely@redhat.com>
 
+	* include/std/ranges (__detail::__convertible_to_non_slicing): New
+	helper concept.
+	(__detail::__pair_like_convertible_to): Remove.
+	(__detail::__pair_like_convertible_from): Add requirements for
+	non-slicing conversions.
+	(subrange): Constrain constructors with __convertible_to_non_slicing.
+	Remove constructors from pair-like types. Add new deduction guide.
+	* testsuite/std/ranges/subrange/lwg3282_neg.cc: New test.
+
 	* include/bits/iterator_concepts.h (iter_move): Add declaration to
 	prevent unqualified lookup finding a suitable declaration (LWG 3247).
 
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index b0806750a08..b348ba2cfcb 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -214,6 +214,12 @@ namespace ranges
 
   namespace __detail
   {
+    template<class _From, class _To>
+      concept __convertible_to_non_slicing = convertible_to<_From, _To>
+	&& !(is_pointer_v<decay_t<_From>> && is_pointer_v<decay_t<_To>>
+	    && __not_same_as<remove_pointer_t<decay_t<_From>>,
+			     remove_pointer_t<decay_t<_To>>>);
+
     template<typename _Tp>
       concept __pair_like
 	= !is_reference_v<_Tp> && requires(_Tp __t)
@@ -226,19 +232,12 @@ namespace ranges
 	  { get<1>(__t) } -> convertible_to<const tuple_element_t<1, _Tp>&>;
 	};
 
-    template<typename _Tp, typename _Up, typename _Vp>
-      concept __pair_like_convertible_to
-	= !range<_Tp> && __pair_like<remove_reference_t<_Tp>>
-	&& requires(_Tp&& __t)
-	{
-	  { get<0>(std::forward<_Tp>(__t)) } -> convertible_to<_Up>;
-	  { get<1>(std::forward<_Tp>(__t)) } -> convertible_to<_Vp>;
-	};
-
     template<typename _Tp, typename _Up, typename _Vp>
       concept __pair_like_convertible_from
 	= !range<_Tp> && __pair_like<_Tp>
-	&& constructible_from<_Tp, _Up, _Vp>;
+	&& constructible_from<_Tp, _Up, _Vp>
+	&& __convertible_to_non_slicing<_Up, tuple_element_t<0, _Tp>>
+	&& convertible_to<_Vp, tuple_element_t<1, _Tp>>;
 
     template<typename _Tp>
       concept __iterator_sentinel_pair
@@ -277,12 +276,13 @@ namespace ranges
       subrange() = default;
 
       constexpr
-      subrange(_It __i, _Sent __s) requires (!_S_store_size)
+      subrange(__detail::__convertible_to_non_slicing<_It> auto __i, _Sent __s)
+	requires (!_S_store_size)
       : _M_begin(std::move(__i)), _M_end(__s)
       { }
 
       constexpr
-      subrange(_It __i, _Sent __s,
+      subrange(__detail::__convertible_to_non_slicing<_It> auto __i, _Sent __s,
 	       __detail::__make_unsigned_like_t<iter_difference_t<_It>> __n)
 	requires (_Kind == subrange_kind::sized)
       : _M_begin(std::move(__i)), _M_end(__s)
@@ -295,7 +295,7 @@ namespace ranges
 
       template<__detail::__not_same_as<subrange> _Rng>
 	requires borrowed_range<_Rng>
-	  && convertible_to<iterator_t<_Rng>, _It>
+	  && __detail::__convertible_to_non_slicing<iterator_t<_Rng>, _It>
 	  && convertible_to<sentinel_t<_Rng>, _Sent>
 	constexpr
 	subrange(_Rng&& __r) requires (!_S_store_size || sized_range<_Rng>)
@@ -306,7 +306,7 @@ namespace ranges
 	}
 
       template<borrowed_range _Rng>
-	requires convertible_to<iterator_t<_Rng>, _It>
+	requires __detail::__convertible_to_non_slicing<iterator_t<_Rng>, _It>
 	  && convertible_to<sentinel_t<_Rng>, _Sent>
 	constexpr
 	subrange(_Rng&& __r,
@@ -315,23 +315,6 @@ namespace ranges
 	: subrange{ranges::begin(__r), ranges::end(__r), __n}
 	{ }
 
-      template<__detail::__not_same_as<subrange> _PairLike>
-	requires __detail::__pair_like_convertible_to<_PairLike, _It, _Sent>
-	constexpr
-	subrange(_PairLike&& __r) requires (!_S_store_size)
-	: subrange{std::get<0>(std::forward<_PairLike>(__r)),
-		   std::get<1>(std::forward<_PairLike>(__r))}
-	{ }
-
-      template<__detail::__pair_like_convertible_to<_It, _Sent> _PairLike>
-	constexpr
-	subrange(_PairLike&& __r,
-		 __detail::__make_unsigned_like_t<iter_difference_t<_It>> __n)
-	requires (_Kind == subrange_kind::sized)
-	: subrange{std::get<0>(std::forward<_PairLike>(__r)),
-		   std::get<1>(std::forward<_PairLike>(__r)), __n}
-	{ }
-
       template<__detail::__not_same_as<subrange> _PairLike>
 	requires __detail::__pair_like_convertible_from<_PairLike, const _It&,
 							const _Sent&>
@@ -402,6 +385,9 @@ namespace ranges
       }
     };
 
+  template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
+    subrange(_It, _Sent) -> subrange<_It, _Sent>;
+
   template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
     subrange(_It, _Sent,
 	     __detail::__make_unsigned_like_t<iter_difference_t<_It>>)
diff --git a/libstdc++-v3/testsuite/std/ranges/subrange/lwg3282_neg.cc b/libstdc++-v3/testsuite/std/ranges/subrange/lwg3282_neg.cc
new file mode 100644
index 00000000000..5c2f1de45ad
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/ranges/subrange/lwg3282_neg.cc
@@ -0,0 +1,31 @@
+// 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 <ranges>
+
+using std::ranges::subrange;
+
+// LWG 3282. subrange converting constructor should disallow derived to base
+// conversions
+
+struct Base {};
+struct Derived : Base {};
+subrange<Derived*> sd;
+subrange<Base*> sb = sd; // { dg-error "conversion" }

commit 59aa9e577eb2b182374f5421828687c93b81ad3d
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Feb 19 16:43:07 2020 +0000

    libstdc++: ranges::iter_move should perform ADL-only lookup (LWG 3247)
    
            * include/bits/iterator_concepts.h (iter_move): Add declaration to
            prevent unqualified lookup finding a suitable declaration (LWG 3247).

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 067cf8343f6..689bee8c2a9 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,8 @@
 2020-02-19  Jonathan Wakely  <jwakely@redhat.com>
 
+	* include/bits/iterator_concepts.h (iter_move): Add declaration to
+	prevent unqualified lookup finding a suitable declaration (LWG 3247).
+
 	* include/std/memory_resource (polymorphic_allocator::allocate)
 	(polymorphic_allocator::allocate_object): Change type of exception to
 	bad_array_new_length (LWG 3237).
diff --git a/libstdc++-v3/include/bits/iterator_concepts.h b/libstdc++-v3/include/bits/iterator_concepts.h
index 792b3262106..08e622259b4 100644
--- a/libstdc++-v3/include/bits/iterator_concepts.h
+++ b/libstdc++-v3/include/bits/iterator_concepts.h
@@ -79,6 +79,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   {
     namespace __cust_imove
     {
+      void iter_move();
+
       template<typename _Tp>
 	concept __adl_imove
 	  = (std::__detail::__class_or_enum<remove_reference_t<_Tp>>)

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [committed] libstdc++: Implement LWG issues 3329, 3331, 3360, 3364, 3385
  2020-02-19 21:22   ` [committed] libstdc++: Implement LWG issues 3247, 3282 Jonathan Wakely
@ 2020-02-19 22:13     ` Jonathan Wakely
  0 siblings, 0 replies; 5+ messages in thread
From: Jonathan Wakely @ 2020-02-19 22:13 UTC (permalink / raw)
  To: libstdc++, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 300 bytes --]

make common_iterator<I, S> require copyable<I> (LWG 3385)
Add default-initializers to views (LWG 3364)
Simplify std::three_way_comparable_with (LWG 3360)
Simplify std::totally_ordered (LWG 3331)
Simplify std::totally_ordered_with (LWG 3329)

Tested powerpc64le-linux, committed to master.



[-- Attachment #2: patch.txt --]
[-- Type: text/x-patch, Size: 13441 bytes --]

commit 1b425f3ac516f7250e9f7eac7cd4fe0908ccfa4e
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Feb 19 21:56:29 2020 +0000

    libstdc++: make common_iterator<I, S> require copyable<I> (LWG 3385)
    
            * include/bits/stl_iterator.h (common_iterator): Add copyable<I>
            requirement (LWG 3385).
            * testsuite/24_iterators/headers/iterator/synopsis_c++20.cc: Adjust
            expected declaration.

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index ef91b80ef45..7f3f8876957 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,10 @@
 2020-02-19  Jonathan Wakely  <jwakely@redhat.com>
 
+	* include/bits/stl_iterator.h (common_iterator): Add copyable<I>
+	requirement (LWG 3385).
+	* testsuite/24_iterators/headers/iterator/synopsis_c++20.cc: Adjust
+	expected declaration.
+
 	* include/std/ranges (take_while_view, drop_view, drop_while_view)
 	(elements_view:_Iterator): Initialize data members (LWG 3364).
 
diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h
index fc9d442b475..372df223113 100644
--- a/libstdc++-v3/include/bits/stl_iterator.h
+++ b/libstdc++-v3/include/bits/stl_iterator.h
@@ -1426,7 +1426,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   /// An iterator/sentinel adaptor for representing a non-common range.
   template<input_or_output_iterator _It, sentinel_for<_It> _Sent>
-    requires (!same_as<_It, _Sent>)
+    requires (!same_as<_It, _Sent>) && copyable<_It>
   class common_iterator
   {
     template<typename _Tp, typename _Up>
diff --git a/libstdc++-v3/testsuite/24_iterators/headers/iterator/synopsis_c++20.cc b/libstdc++-v3/testsuite/24_iterators/headers/iterator/synopsis_c++20.cc
index 4d8eca31d38..fbe116be2fd 100644
--- a/libstdc++-v3/testsuite/24_iterators/headers/iterator/synopsis_c++20.cc
+++ b/libstdc++-v3/testsuite/24_iterators/headers/iterator/synopsis_c++20.cc
@@ -56,7 +56,7 @@ namespace std
   template<semiregular S> class move_sentinel;
 
   template<input_or_output_iterator I, sentinel_for<I> S>
-    requires (!same_as<I, S>)
+    requires (!same_as<I, S>) && copyable<I>
     class common_iterator;
 
   template<class I, class S>

commit 7433536b3d864c0d8d5180348690e1c280a3eaf2
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Feb 19 22:00:14 2020 +0000

    libstdc++: Add default-initializers to views (LWG 3364)
    
            * include/std/ranges (take_while_view, drop_view, drop_while_view)
            (elements_view:_Iterator): Initialize data members (LWG 3364).

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 622c2948eab..ef91b80ef45 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,8 @@
 2020-02-19  Jonathan Wakely  <jwakely@redhat.com>
 
+	* include/std/ranges (take_while_view, drop_view, drop_while_view)
+	(elements_view:_Iterator): Initialize data members (LWG 3364).
+
 	* libsupc++/compare (three_way_comparable): Remove always-false check
 	that should have been removed with weak_equality (P1959R0).
 	(three_way_comparable_with): Likewise. Reorder requirements (LWG 3360).
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index b348ba2cfcb..7a66491f2e4 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -2008,7 +2008,7 @@ namespace views
 	  { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }
 	};
 
-      _Vp _M_base;
+      _Vp _M_base = _Vp();
       __detail::__box<_Pred> _M_pred;
 
     public:
@@ -2068,8 +2068,8 @@ namespace views
     class drop_view : public view_interface<drop_view<_Vp>>
     {
     private:
-      _Vp _M_base;
-      range_difference_t<_Vp> _M_count;
+      _Vp _M_base = _Vp();
+      range_difference_t<_Vp> _M_count = 0;
 
     public:
       drop_view() = default;
@@ -2147,7 +2147,7 @@ namespace views
     class drop_while_view : public view_interface<drop_while_view<_Vp, _Pred>>
     {
     private:
-      _Vp _M_base;
+      _Vp _M_base = _Vp();
       __detail::__box<_Pred> _M_pred;
 
     public:
@@ -3179,7 +3179,7 @@ namespace views
 	{
 	  using _Base = conditional_t<_Const, const _Vp, _Vp>;
 
-	  iterator_t<_Base> _M_current;
+	  iterator_t<_Base> _M_current = iterator_t<_Base>();
 
 	  friend _Iterator<!_Const>;
 

commit 256f67aa078de0e7bf53a0870c2cb87ab90cda09
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Feb 19 21:45:59 2020 +0000

    libstdc++: Simplify std::three_way_comparable_with (LWG 3360)
    
    This also removes a useless condition that was supposed to be removed by
    the P1959R0 changes, but left in when that was implemented.
    
            * libsupc++/compare (three_way_comparable): Remove always-false check
            that should have been removed with weak_equality (P1959R0).
            (three_way_comparable_with): Likewise. Reorder requirements (LWG 3360).

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 1711a359256..622c2948eab 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,9 @@
 2020-02-19  Jonathan Wakely  <jwakely@redhat.com>
 
+	* libsupc++/compare (three_way_comparable): Remove always-false check
+	that should have been removed with weak_equality (P1959R0).
+	(three_way_comparable_with): Likewise. Reorder requirements (LWG 3360).
+
 	* include/std/concepts (__detail::__partially_ordered_with): Move here
 	from <compare>.
 	(totally_ordered, totally_ordered_with): Use __partially_ordered_with
diff --git a/libstdc++-v3/libsupc++/compare b/libstdc++-v3/libsupc++/compare
index a74ebc845bf..b88b691b9e1 100644
--- a/libstdc++-v3/libsupc++/compare
+++ b/libstdc++-v3/libsupc++/compare
@@ -417,8 +417,7 @@ namespace std
   template<typename _Tp, typename _Cat = partial_ordering>
     concept three_way_comparable
       = __detail::__weakly_eq_cmp_with<_Tp, _Tp>
-      && (!convertible_to<_Cat, partial_ordering>
-	  || __detail::__partially_ordered_with<_Tp, _Tp>)
+      && __detail::__partially_ordered_with<_Tp, _Tp>
       && requires(const remove_reference_t<_Tp>& __a,
 		  const remove_reference_t<_Tp>& __b) {
 	{ __a <=> __b } -> __detail::__compares_as<_Cat>;
@@ -426,16 +425,15 @@ namespace std
 
   template<typename _Tp, typename _Up, typename _Cat = partial_ordering>
     concept three_way_comparable_with
-      = __detail::__weakly_eq_cmp_with<_Tp, _Up>
-      && (!convertible_to<_Cat, partial_ordering>
-	  || __detail::__partially_ordered_with<_Tp, _Up>)
-      && three_way_comparable<_Tp, _Cat>
+      = three_way_comparable<_Tp, _Cat>
       && three_way_comparable<_Up, _Cat>
       && common_reference_with<const remove_reference_t<_Tp>&,
 			       const remove_reference_t<_Up>&>
       && three_way_comparable<
 	  common_reference_t<const remove_reference_t<_Tp>&,
 			     const remove_reference_t<_Up>&>, _Cat>
+      && __detail::__weakly_eq_cmp_with<_Tp, _Up>
+      && __detail::__partially_ordered_with<_Tp, _Up>
       && requires(const remove_reference_t<_Tp>& __t,
 		  const remove_reference_t<_Up>& __u) {
 	{ __t <=> __u } -> __detail::__compares_as<_Cat>;

commit 0294dc5f4eec5a07d70fac48f75c498c3b1a339b
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Feb 19 21:40:03 2020 +0000

    libstdc++: Simplify std::totally_ordered (LWG 3331)
    
            * include/std/concepts (__detail::__partially_ordered_with): Move here
            from <compare>.
            (totally_ordered, totally_ordered_with): Use __partially_ordered_with
            to simplify definition (LWG 3331).
            * libsupc++/compare (__detail::__partially_ordered_with): Move to
            <concepts>.

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 3941bcbe7ba..1711a359256 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,12 @@
 2020-02-19  Jonathan Wakely  <jwakely@redhat.com>
 
+	* include/std/concepts (__detail::__partially_ordered_with): Move here
+	from <compare>.
+	(totally_ordered, totally_ordered_with): Use __partially_ordered_with
+	to simplify definition (LWG 3331).
+	* libsupc++/compare (__detail::__partially_ordered_with): Move to
+	<concepts>.
+
 	* include/std/concepts (totally_ordered_with): Remove redundant
 	requirement (LWG 3329).
 
diff --git a/libstdc++-v3/include/std/concepts b/libstdc++-v3/include/std/concepts
index be125c636a1..ba232e953ec 100644
--- a/libstdc++-v3/include/std/concepts
+++ b/libstdc++-v3/include/std/concepts
@@ -297,16 +297,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 						__detail::__cref<_Up>>>
       && __detail::__weakly_eq_cmp_with<_Tp, _Up>;
 
+  namespace __detail
+  {
+    template<typename _Tp, typename _Up>
+      concept __partially_ordered_with
+	= requires(const remove_reference_t<_Tp>& __t,
+		   const remove_reference_t<_Up>& __u) {
+	  { __t <  __u } -> __boolean_testable;
+	  { __t >  __u } -> __boolean_testable;
+	  { __t <= __u } -> __boolean_testable;
+	  { __t >= __u } -> __boolean_testable;
+	  { __u <  __t } -> __boolean_testable;
+	  { __u >  __t } -> __boolean_testable;
+	  { __u <= __t } -> __boolean_testable;
+	  { __u >= __t } -> __boolean_testable;
+	};
+  } // namespace __detail
+
   // [concept.totallyordered], concept totally_ordered
   template<typename _Tp>
     concept totally_ordered
       = equality_comparable<_Tp>
-      && requires(__detail::__cref<_Tp> __a, __detail::__cref<_Tp> __b) {
-	{ __a <  __b } -> __detail::__boolean_testable;
-	{ __a >  __b } -> __detail::__boolean_testable;
-	{ __a <= __b } -> __detail::__boolean_testable;
-	{ __a >= __b } -> __detail::__boolean_testable;
-      };
+      && __detail::__partially_ordered_with<_Tp, _Tp>;
 
   template<typename _Tp, typename _Up>
     concept totally_ordered_with
@@ -314,16 +326,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       && equality_comparable_with<_Tp, _Up>
       && totally_ordered<common_reference_t<__detail::__cref<_Tp>,
 					    __detail::__cref<_Up>>>
-      && requires(__detail::__cref<_Tp> __t, __detail::__cref<_Up> __u) {
-	{ __t <  __u } -> __detail::__boolean_testable;
-	{ __t >  __u } -> __detail::__boolean_testable;
-	{ __t <= __u } -> __detail::__boolean_testable;
-	{ __t >= __u } -> __detail::__boolean_testable;
-	{ __u <  __t } -> __detail::__boolean_testable;
-	{ __u >  __t } -> __detail::__boolean_testable;
-	{ __u <= __t } -> __detail::__boolean_testable;
-	{ __u >= __t } -> __detail::__boolean_testable;
-      };
+      && __detail::__partially_ordered_with<_Tp, _Up>;
 
   template<typename _Tp>
     concept regular = semiregular<_Tp> && equality_comparable<_Tp>;
diff --git a/libstdc++-v3/libsupc++/compare b/libstdc++-v3/libsupc++/compare
index ba7db316486..a74ebc845bf 100644
--- a/libstdc++-v3/libsupc++/compare
+++ b/libstdc++-v3/libsupc++/compare
@@ -411,20 +411,6 @@ namespace std
     template<typename _Tp, typename _Cat>
       concept __compares_as
 	= same_as<common_comparison_category_t<_Tp, _Cat>, _Cat>;
-
-    template<typename _Tp, typename _Up>
-      concept __partially_ordered_with
-	= requires(const remove_reference_t<_Tp>& __t,
-		   const remove_reference_t<_Up>& __u) {
-	  { __t <  __u } -> __boolean_testable;
-	  { __t >  __u } -> __boolean_testable;
-	  { __t <= __u } -> __boolean_testable;
-	  { __t >= __u } -> __boolean_testable;
-	  { __u <  __t } -> __boolean_testable;
-	  { __u >  __t } -> __boolean_testable;
-	  { __u <= __t } -> __boolean_testable;
-	  { __u >= __t } -> __boolean_testable;
-	};
   } // namespace __detail
 
   // [cmp.concept], concept three_way_comparable

commit 241ed965509ac931e9ae5f331d0294c1ee4ccd89
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Feb 19 21:31:06 2020 +0000

    libstdc++: Simplify std::totally_ordered_with (LWG 3329)
    
            * include/std/concepts (totally_ordered_with): Remove redundant
            requirement (LWG 3329).

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 6e22536680f..3941bcbe7ba 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,8 @@
 2020-02-19  Jonathan Wakely  <jwakely@redhat.com>
 
+	* include/std/concepts (totally_ordered_with): Remove redundant
+	requirement (LWG 3329).
+
 	* include/std/ranges (__detail::__convertible_to_non_slicing): New
 	helper concept.
 	(__detail::__pair_like_convertible_to): Remove.
diff --git a/libstdc++-v3/include/std/concepts b/libstdc++-v3/include/std/concepts
index f3db40b798f..be125c636a1 100644
--- a/libstdc++-v3/include/std/concepts
+++ b/libstdc++-v3/include/std/concepts
@@ -311,10 +311,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Tp, typename _Up>
     concept totally_ordered_with
       = totally_ordered<_Tp> && totally_ordered<_Up>
-      && common_reference_with<__detail::__cref<_Tp>, __detail::__cref<_Up>>
+      && equality_comparable_with<_Tp, _Up>
       && totally_ordered<common_reference_t<__detail::__cref<_Tp>,
 					    __detail::__cref<_Up>>>
-      && equality_comparable_with<_Tp, _Up>
       && requires(__detail::__cref<_Tp> __t, __detail::__cref<_Up> __u) {
 	{ __t <  __u } -> __detail::__boolean_testable;
 	{ __t >  __u } -> __detail::__boolean_testable;

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-02-19 22:13 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-19 12:47 [committed] libstdc++: Implement LWG issues 3398, 3379, 3304, 3321, 3280, 3335 Jonathan Wakely
2020-02-19 13:01 ` Jonathan Wakely
2020-02-19 15:45 ` [committed] libstdc++: Implement LWG issues 3320, 3369, 3200, 3348, 3237 Jonathan Wakely
2020-02-19 21:22   ` [committed] libstdc++: Implement LWG issues 3247, 3282 Jonathan Wakely
2020-02-19 22:13     ` [committed] libstdc++: Implement LWG issues 3329, 3331, 3360, 3364, 3385 Jonathan Wakely

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).