[gcc r15-5297] libstdc++: Fix indentation in std::list::emplace_back

2024-11-14 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:71f221a8bee6274f37af99138b41c3ae451527ef

commit r15-5297-g71f221a8bee6274f37af99138b41c3ae451527ef
Author: Jonathan Wakely 
Date:   Fri Nov 15 00:00:38 2024 +

libstdc++: Fix indentation in std::list::emplace_back

libstdc++-v3/ChangeLog:

* include/bits/stl_list.h (list::emplace_back): Fix indentation.

Diff:
---
 libstdc++-v3/include/bits/stl_list.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/bits/stl_list.h 
b/libstdc++-v3/include/bits/stl_list.h
index 3c313cec1d89..7deb04b4bfe4 100644
--- a/libstdc++-v3/include/bits/stl_list.h
+++ b/libstdc++-v3/include/bits/stl_list.h
@@ -1410,7 +1410,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
{
  this->_M_insert(end(), std::forward<_Args>(__args)...);
 #if __cplusplus > 201402L
-   return back();
+ return back();
 #endif
}
 #endif


[gcc r15-5286] libstdc++: Make _GLIBCXX_NODISCARD work for C++11 and C++14

2024-11-14 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:e627a941dc463db08f68d94f5ade74665b3070d4

commit r15-5286-ge627a941dc463db08f68d94f5ade74665b3070d4
Author: Jonathan Wakely 
Date:   Mon Feb 26 11:40:46 2024 +

libstdc++: Make _GLIBCXX_NODISCARD work for C++11 and C++14

The _GLIBCXX_NODISCARD macro only expands to [[__nodiscard__]] for C++17
and later, but all supported compilers will allow us to use that for
C++11 and C++14 too. Enable it for those older standards, to give
improved diagnostics for users of those older standards.

libstdc++-v3/ChangeLog:

* include/bits/c++config (_GLIBCXX_NODISCARD): Expand for C++11
and C++14.
* testsuite/22_locale/locale/cons/12438.cc: Adjust dg-warning to
expect nodiscard warnings for C++11 and C++14 as well.
* testsuite/22_locale/locale/operations/2.cc: Likewise.
* testsuite/25_algorithms/equal/debug/1_neg.cc: Likewise.
* testsuite/25_algorithms/equal/debug/2_neg.cc: Likewise.
* testsuite/25_algorithms/equal/debug/3_neg.cc: Likewise.
* testsuite/25_algorithms/find_first_of/concept_check_1.cc:
Likewise.
* testsuite/25_algorithms/is_permutation/2.cc: Likewise.
* testsuite/25_algorithms/lexicographical_compare/71545.cc:
Likewise.
* testsuite/25_algorithms/lower_bound/33613.cc: Likewise.
* testsuite/25_algorithms/lower_bound/debug/irreflexive.cc:
Likewise.
* testsuite/25_algorithms/lower_bound/debug/partitioned_neg.cc:
Likewise.
* 
testsuite/25_algorithms/lower_bound/debug/partitioned_pred_neg.cc: Likewise.
* testsuite/25_algorithms/minmax/3.cc: Likewise.
* testsuite/25_algorithms/search/78346.cc: Likewise.
* testsuite/25_algorithms/search_n/58358.cc: Likewise.
* testsuite/25_algorithms/unique/1.cc: Likewise.
* testsuite/25_algorithms/unique/11480.cc: Likewise.
* testsuite/25_algorithms/upper_bound/33613.cc: Likewise.
* testsuite/25_algorithms/upper_bound/debug/partitioned_neg.cc:
Likewise.
* 
testsuite/25_algorithms/upper_bound/debug/partitioned_pred_neg.cc: Likewise.
* testsuite/27_io/ios_base/types/fmtflags/bitmask_operators.cc:
Likewise.
* testsuite/27_io/ios_base/types/iostate/bitmask_operators.cc:
Likewise.
* testsuite/27_io/ios_base/types/openmode/bitmask_operators.cc:
Likewise.
* testsuite/ext/concept_checks.cc: Likewise.
* testsuite/ext/is_heap/47709.cc: Likewise.
* testsuite/ext/is_sorted/cxx0x.cc: Likewise.

Diff:
---
 libstdc++-v3/include/bits/c++config   | 2 +-
 libstdc++-v3/testsuite/22_locale/locale/cons/12438.cc | 2 +-
 libstdc++-v3/testsuite/22_locale/locale/operations/2.cc   | 2 +-
 libstdc++-v3/testsuite/25_algorithms/equal/debug/1_neg.cc | 2 +-
 libstdc++-v3/testsuite/25_algorithms/equal/debug/2_neg.cc | 2 +-
 libstdc++-v3/testsuite/25_algorithms/equal/debug/3_neg.cc | 2 +-
 .../testsuite/25_algorithms/find_first_of/concept_check_1.cc  | 2 +-
 libstdc++-v3/testsuite/25_algorithms/is_permutation/2.cc  | 2 +-
 .../testsuite/25_algorithms/lexicographical_compare/71545.cc  | 2 +-
 libstdc++-v3/testsuite/25_algorithms/lower_bound/33613.cc | 2 +-
 .../testsuite/25_algorithms/lower_bound/debug/irreflexive.cc  | 2 +-
 .../testsuite/25_algorithms/lower_bound/debug/partitioned_neg.cc  | 2 +-
 .../25_algorithms/lower_bound/debug/partitioned_pred_neg.cc   | 2 +-
 libstdc++-v3/testsuite/25_algorithms/minmax/3.cc  | 2 +-
 libstdc++-v3/testsuite/25_algorithms/search/78346.cc  | 2 +-
 libstdc++-v3/testsuite/25_algorithms/search_n/58358.cc| 2 +-
 libstdc++-v3/testsuite/25_algorithms/unique/1.cc  | 2 +-
 libstdc++-v3/testsuite/25_algorithms/unique/11480.cc  | 2 +-
 libstdc++-v3/testsuite/25_algorithms/upper_bound/33613.cc | 2 +-
 .../testsuite/25_algorithms/upper_bound/debug/partitioned_neg.cc  | 2 +-
 .../25_algorithms/upper_bound/debug/partitioned_pred_neg.cc   | 2 +-
 .../testsuite/27_io/ios_base/types/fmtflags/bitmask_operators.cc  | 8 
 .../testsuite/27_io/ios_base/types/iostate/bitmask_operators.cc   | 8 
 .../testsuite/27_io/ios_base/types/openmode/bitmask_operators.cc  | 8 
 libstdc++-v3/testsuite/ext/concept_checks.cc  | 8 
 libstdc++-v3/testsuite/ext/is_heap/47709.cc   | 3 +--
 libstdc++-v3/testsuite/ext/is_sorted/cxx0x.cc | 3 +--
 27 files changed, 39 insertions(+), 41 deletions(-)

diff --git a/libstdc++-v3/include/bits/c++config 
b/libstdc++-v3/include/bits/c++config
index 1076803a8655..236906d2f79f 100644
--- a/libstdc++-v3/include/bits/

[gcc r15-5254] libstdc++: Add missing constraint to operator+ for std::move_iterator

2024-11-14 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:f91e34644e66b2eb7f4930f17a30da9f49e7d4d2

commit r15-5254-gf91e34644e66b2eb7f4930f17a30da9f49e7d4d2
Author: Jonathan Wakely 
Date:   Thu Nov 14 10:50:34 2024 +

libstdc++: Add missing constraint to operator+ for std::move_iterator

This constraint was added by the One Ranges proposal (P0896R4) and
then fixed by LWG 3293, but it was missing from libstdc++.

libstdc++-v3/ChangeLog:

* include/bits/stl_iterator.h (operator+): Add constraint to
move_iterator operator.
* testsuite/24_iterators/move_iterator/rel_ops_c++20.cc:

Diff:
---
 libstdc++-v3/include/bits/stl_iterator.h |  4 
 .../testsuite/24_iterators/move_iterator/rel_ops_c++20.cc| 12 
 2 files changed, 16 insertions(+)

diff --git a/libstdc++-v3/include/bits/stl_iterator.h 
b/libstdc++-v3/include/bits/stl_iterator.h
index 5ea901bf1f6c..e872598d7d8f 100644
--- a/libstdc++-v3/include/bits/stl_iterator.h
+++ b/libstdc++-v3/include/bits/stl_iterator.h
@@ -1731,6 +1731,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 inline _GLIBCXX17_CONSTEXPR bool
 operator==(const move_iterator<_Iterator>& __x,
   const move_iterator<_Iterator>& __y)
+// N.B. No contraints, x.base() == y.base() is always well-formed.
 { return __x.base() == __y.base(); }
 
 #ifdef __cpp_lib_three_way_comparison
@@ -1791,6 +1792,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 inline _GLIBCXX17_CONSTEXPR move_iterator<_Iterator>
 operator+(typename move_iterator<_Iterator>::difference_type __n,
  const move_iterator<_Iterator>& __x)
+#ifdef __glibcxx_concepts
+requires requires { { __x.base() + __n } -> same_as<_Iterator>; }
+#endif
 { return __x + __n; }
 
   template
diff --git a/libstdc++-v3/testsuite/24_iterators/move_iterator/rel_ops_c++20.cc 
b/libstdc++-v3/testsuite/24_iterators/move_iterator/rel_ops_c++20.cc
index b2c1fe0e9f8d..deb177222578 100644
--- a/libstdc++-v3/testsuite/24_iterators/move_iterator/rel_ops_c++20.cc
+++ b/libstdc++-v3/testsuite/24_iterators/move_iterator/rel_ops_c++20.cc
@@ -18,6 +18,7 @@
 // { dg-do compile { target c++20 } }
 
 #include 
+#include 
 
 template
 struct Iter
@@ -141,3 +142,14 @@ static_assert( cend > beg );
 static_assert( beg <= cend );
 static_assert( cend >= beg );
 static_assert( std::is_lt(beg <=> cend) );
+
+template
+  concept has_plus = requires(std::iter_difference_t n, I i) {
+   { n + i } -> std::same_as;
+  };
+
+using namespace __gnu_test;
+using MBI = std::move_iterator>;
+static_assert( ! has_plus );
+using MRI = std::move_iterator>;
+static_assert( has_plus );


[gcc r13-9185] libstdc++: Suppress deprecation messages from [PR101228]

2024-11-13 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:3e2b297b0bb77317e759a180a5d4b701f6e5e6e4

commit r13-9185-g3e2b297b0bb77317e759a180a5d4b701f6e5e6e4
Author: Jonathan Wakely 
Date:   Thu Feb 29 17:13:49 2024 +

libstdc++: Suppress deprecation messages from  [PR101228]

libstdc++-v3/ChangeLog:

PR libstdc++/101228
* include/pstl/parallel_backend_tbb.h 
(TBB_SUPPRESS_DEPRECATED_MESSAGES):
Define before including  then undef afterwards.

(cherry picked from commit c608b57f77a47179899666940c3b8b6a2e5435b2)

Diff:
---
 libstdc++-v3/include/pstl/parallel_backend_tbb.h | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/libstdc++-v3/include/pstl/parallel_backend_tbb.h 
b/libstdc++-v3/include/pstl/parallel_backend_tbb.h
index 3fd1a06ebd89..413c7843bb8b 100644
--- a/libstdc++-v3/include/pstl/parallel_backend_tbb.h
+++ b/libstdc++-v3/include/pstl/parallel_backend_tbb.h
@@ -15,6 +15,11 @@
 
 #include "parallel_backend_utils.h"
 
+#ifndef TBB_SUPPRESS_DEPRECATED_MESSAGES
+# define TBB_SUPPRESS_DEPRECATED_MESSAGES 1
+# define _GLIBCXX_UNDEF_SUPPRESS
+#endif
+
 // Bring in minimal required subset of Intel TBB
 #include 
 #include 
@@ -25,6 +30,11 @@
 #include 
 #include 
 
+#ifdef _GLIBCXX_UNDEF_SUPPRESS
+# undef TBB_SUPPRESS_DEPRECATED_MESSAGES
+# undef _GLIBCXX_UNDEF_SUPPRESS
+#endif
+
 #if TBB_INTERFACE_VERSION < 1
 #error Intel(R) Threading Building Blocks 2018 is required; older versions 
are not supported.
 #endif


[gcc r15-5223] libstdc++: Refactor std::hash specializations

2024-11-13 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:01ba02caa924058af539d37970d2b07f22d9fdf7

commit r15-5223-g01ba02caa924058af539d37970d2b07f22d9fdf7
Author: Jonathan Wakely 
Date:   Thu Oct 31 16:29:18 2024 +

libstdc++: Refactor std::hash specializations

This attempts to simplify and clean up our std::hash code. The primary
benefit is improved diagnostics for users when they do something wrong
involving std::hash or unordered containers. An additional benefit is
that for the unstable ABI (--enable-symvers=gnu-versioned-namespace) we
can reduce the memory footprint of several std::hash specializations.

In the current design, __hash_enum is a base class of the std::hash
primary template, but the partial specialization of __hash_enum for
non-enum types is disabled.  This means that if a user forgets to
specialize std::hash for their class type (or forgets to use a custom
hash function for unordered containers) they get error messages about
std::__hash_enum not being constructible.  This is confusing when there
is no enum type involved: why should users care about __hash_enum not
being constructible if they're not trying to hash enums?

This change makes the std::hash primary template only derive from
__hash_enum when the template argument type is an enum. Otherwise, it
derives directly from a new class template, __hash_not_enabled. This new
class template defines the deleted members that cause a given std::hash
specialization to be a disabled specialization (as per P0513R0). Now
when users try to use a disabled specialization, they get more
descriptive errors that mention __hash_not_enabled instead of
__hash_enum.

Additionally, adjust __hash_base to remove the deprecated result_type
and argument_type typedefs for C++20 and later.

In the current code we use a __poison_hash base class in the std::hash
specializations for std::unique_ptr, std::optional, and std::variant.
The primary template of __poison_hash has deleted special members, which
is used to conditionally disable the derived std::hash specialization.
This can also result in confusing diagnostics, because seeing "poison"
in an enabled specialization is misleading. Only some uses of
__poison_hash actually "poison" anything, i.e. cause a specialization to
be disabled. In other cases it's just an empty base class that does
nothing.

This change removes __poison_hash and changes the std::hash
specializations that were using it to conditionally derive from
__hash_not_enabled instead. When the std::hash specialization is
enabled, there is no more __poison_hash base class. However, to preserve
the ABI properties of those std::hash specializations, we need to
replace __poison_hash with some other empty base class. This is needed
because in the current code std::hash> has
two __poison_hash base classes, which must have unique addresses,
so sizeof(std::hash>) == 2. To preserve
this unfortunate property, a new __hash_empty_base class is used as a
base class to re-introduce du0plicate base classes that increase the
class size. For the unstable ABI we don't use __hash_empty_base so the
std::hash> specializations are always size 1, and
the class hierarchy is much simpler so will compile faster.

Additionally, remove the result_type and argument_type typedefs from all
disabled specializations of std::hash for std::unique_ptr,
std::optional, and std::variant. Those typedefs are useless for disabled
specializations, and although the standard doesn't say they must *not*
be present for disabled specializations, it certainly only requires them
for enabled specializations. Finally, for C++20 the typedefs are also
removed from enabled specializations of std::hash for std::unique_ptr,
std::optional, and std::variant.

libstdc++-v3/ChangeLog:

* doc/xml/manual/evolution.xml: Document removal of nested types
from std::hash specializations.
* doc/html/manual/api.html: Regenerate.
* include/bits/functional_hash.h (__hash_base): Remove
deprecated nested types for C++20.
(__hash_empty_base): Define new class template.
(__is_hash_enabled_for): Define new variable template.
(__poison_hash): Remove.
(__hash_not_enabled): Define new class template.
(__hash_enum): Remove partial specialization for non-enums.
(hash): Derive from __hash_not_enabled for non-enums, instead of
__hash_enum.
* include/bits/unique_ptr.h (__uniq_ptr_hash): Derive from
__hash_base. Conditionally derive from __hash_empty_base.
(__uniq_ptr_hash<>): Remove disabled specialization.
(hash): Do not derive from __hash_base unconditionally.
Conditionally derive from either __uniq_p

[gcc r15-5217] libstdc++: Use RAII in _Hashtable

2024-11-13 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:d2970e86c4de89b4ba38fa935f1be65681970c69

commit r15-5217-gd2970e86c4de89b4ba38fa935f1be65681970c69
Author: Jonathan Wakely 
Date:   Fri Nov 1 22:20:22 2024 +

libstdc++: Use RAII in _Hashtable

Use scoped guard types to clean up if an exception is thrown. This
allows some try-catch blocks to be removed.

libstdc++-v3/ChangeLog:

* include/bits/hashtable.h (operator=(const _Hashtable&)): Use
RAII instead of try-catch.
(_M_assign(_Ht&&, _NodeGenerator&)): Likewise.

Reviewed-by: François Dumont 

Diff:
---
 libstdc++-v3/include/bits/hashtable.h | 99 +++
 1 file changed, 55 insertions(+), 44 deletions(-)

diff --git a/libstdc++-v3/include/bits/hashtable.h 
b/libstdc++-v3/include/bits/hashtable.h
index f1c30896bcb0..a46a94e2ecd5 100644
--- a/libstdc++-v3/include/bits/hashtable.h
+++ b/libstdc++-v3/include/bits/hashtable.h
@@ -1307,17 +1307,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  _M_bucket_count = __ht._M_bucket_count;
  _M_element_count = __ht._M_element_count;
  _M_rehash_policy = __ht._M_rehash_policy;
- __try
-   {
- _M_assign(__ht);
-   }
- __catch(...)
-   {
- // _M_assign took care of deallocating all memory. Now we
- // must make sure this instance remains in a usable state.
- _M_reset();
- __throw_exception_again;
-   }
+
+ struct _Guard
+ {
+   ~_Guard() { if (_M_ht) _M_ht->_M_reset(); }
+   _Hashtable* _M_ht;
+ };
+ // If _M_assign exits via an exception it will have deallocated
+ // all memory. This guard will ensure *this is in a usable state.
+ _Guard __guard{this};
+ _M_assign(__ht);
+ __guard._M_ht = nullptr;
  return *this;
}
  std::__alloc_on_copy(__this_alloc, __that_alloc);
@@ -1390,46 +1390,57 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
   _M_assign(_Ht&& __ht, _NodeGenerator& __node_gen)
   {
-   __buckets_ptr __buckets = nullptr;
-   if (!_M_buckets)
- _M_buckets = __buckets = _M_allocate_buckets(_M_bucket_count);
+   struct _Guard
+   {
+ ~_Guard()
+ {
+   if (_M_ht)
+ {
+   _M_ht->clear();
+   if (_M_dealloc_buckets)
+ _M_ht->_M_deallocate_buckets();
+ }
+ }
+ _Hashtable* _M_ht = nullptr;
+ bool _M_dealloc_buckets = false;
+   };
+   _Guard __guard;
 
-   __try
+   if (!_M_buckets)
  {
-   if (!__ht._M_before_begin._M_nxt)
- return;
+   _M_buckets = _M_allocate_buckets(_M_bucket_count);
+   __guard._M_dealloc_buckets = true;
+ }
 
-   using _FromVal = __conditional_t::value,
-const value_type&, value_type&&>;
+   if (!__ht._M_before_begin._M_nxt)
+ return;
 
-   // First deal with the special first node pointed to by
-   // _M_before_begin.
-   __node_ptr __ht_n = __ht._M_begin();
-   __node_ptr __this_n
- = __node_gen(static_cast<_FromVal>(__ht_n->_M_v()));
-   this->_M_copy_code(*__this_n, *__ht_n);
-   _M_update_bbegin(__this_n);
+   __guard._M_ht = this;
 
-   // Then deal with other nodes.
-   __node_ptr __prev_n = __this_n;
-   for (__ht_n = __ht_n->_M_next(); __ht_n; __ht_n = __ht_n->_M_next())
- {
-   __this_n = __node_gen(static_cast<_FromVal>(__ht_n->_M_v()));
-   __prev_n->_M_nxt = __this_n;
-   this->_M_copy_code(*__this_n, *__ht_n);
-   size_type __bkt = _M_bucket_index(*__this_n);
-   if (!_M_buckets[__bkt])
- _M_buckets[__bkt] = __prev_n;
-   __prev_n = __this_n;
- }
- }
-   __catch(...)
+   using _FromVal = __conditional_t::value,
+const value_type&, value_type&&>;
+
+   // First deal with the special first node pointed to by
+   // _M_before_begin.
+   __node_ptr __ht_n = __ht._M_begin();
+   __node_ptr __this_n
+ = __node_gen(static_cast<_FromVal>(__ht_n->_M_v()));
+   this->_M_copy_code(*__this_n, *__ht_n);
+   _M_update_bbegin(__this_n);
+
+   // Then deal with other nodes.
+   __node_ptr __prev_n = __this_n;
+   for (__ht_n = __ht_n->_M_next(); __ht_n; __ht_n = __ht_n->_M_next())
  {
-   clear();
-   if (__buckets)
- _M_deallocate_buckets();
-   __throw_exception_again;
+   __this_n = __node_gen(static_cast<_FromVal>(__ht_n->

[gcc r15-5215] libstdc++: Add _Hashtable::_M_assign for the common case

2024-11-13 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:37b17388fca498cff718a13aa8d4523f15427c8c

commit r15-5215-g37b17388fca498cff718a13aa8d4523f15427c8c
Author: Jonathan Wakely 
Date:   Fri Nov 1 14:17:38 2024 +

libstdc++: Add _Hashtable::_M_assign for the common case

This adds a convenient _M_assign overload for the common case where the
node generator is the _AllocNode type. Only two places need to call
_M_assign with a _ReuseOrAllocNode node generator, so all the other
calls to _M_assign can use the new overload instead of manually
constructing a node generator.

The _AllocNode::operator(Args&&...) function doesn't need to be a
variadic template. It is only ever called with a single argument of type
const value_type& or value_type&&, so could be simplified. That isn't
done in this commit.

libstdc++-v3/ChangeLog:

* include/bits/hashtable.h (_Hashtable): Remove typedefs for
node generators.
(_Hashtable::_M_assign(_Ht&&)): Add new overload.
(_Hashtable::operator=(initializer_list)): Add local
typedef for node generator.
(_Hashtable::_M_assign_elements): Likewise.
(_Hashtable::operator=(const _Hashtable&)): Use new _M_assign
overload.
(_Hashtable(const _Hashtable&)): Likewise.
(_Hashtable(const _Hashtable&, const allocator_type&)):
Likewise.
(_Hashtable(_Hashtable&&, __node_alloc_type&&, false_type)):
Likewise.
* include/bits/hashtable_policy.h (_Insert): Remove typedef for
node generator.

Reviewed-by: François Dumont 

Diff:
---
 libstdc++-v3/include/bits/hashtable.h| 34 
 libstdc++-v3/include/bits/hashtable_policy.h |  1 -
 2 files changed, 19 insertions(+), 16 deletions(-)

diff --git a/libstdc++-v3/include/bits/hashtable.h 
b/libstdc++-v3/include/bits/hashtable.h
index 23484f711cc5..bf6eed7c1c69 100644
--- a/libstdc++-v3/include/bits/hashtable.h
+++ b/libstdc++-v3/include/bits/hashtable.h
@@ -299,12 +299,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Equal, _Hash, _RangeHash, _Unused,
_RehashPolicy, _Traits>;
 
-  using __reuse_or_alloc_node_gen_t =
-   __detail::_ReuseOrAllocNode<__node_alloc_type>;
-  using __alloc_node_gen_t =
-   __detail::_AllocNode<__node_alloc_type>;
-  using __node_builder_t =
-   __detail::_NodeBuilder<_ExtractKey>;
+  using __node_builder_t = __detail::_NodeBuilder<_ExtractKey>;
 
   // Simple RAII type for managing a node containing an element
   struct _Scoped_node
@@ -480,6 +475,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
void
_M_assign_elements(_Ht&&);
 
+  template
+   void
+   _M_assign(_Ht&& __ht)
+   {
+ __detail::_AllocNode<__node_alloc_type> __alloc_node_gen(*this);
+ _M_assign(std::forward<_Ht>(__ht), __alloc_node_gen);
+   }
+
   template
void
_M_assign(_Ht&&, _NodeGenerator&);
@@ -608,6 +611,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   _Hashtable&
   operator=(initializer_list __l)
   {
+   using __reuse_or_alloc_node_gen_t =
+ __detail::_ReuseOrAllocNode<__node_alloc_type>;
+
__reuse_or_alloc_node_gen_t __roan(_M_begin(), *this);
_M_before_begin._M_nxt = nullptr;
clear();
@@ -1308,10 +1314,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  _M_bucket_count = __ht._M_bucket_count;
  _M_element_count = __ht._M_element_count;
  _M_rehash_policy = __ht._M_rehash_policy;
- __alloc_node_gen_t __alloc_node_gen(*this);
  __try
{
- _M_assign(__ht, __alloc_node_gen);
+ _M_assign(__ht);
}
  __catch(...)
{
@@ -1340,6 +1345,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 _Hash, _RangeHash, _Unused, _RehashPolicy, _Traits>::
   _M_assign_elements(_Ht&& __ht)
   {
+   using __reuse_or_alloc_node_gen_t =
+ __detail::_ReuseOrAllocNode<__node_alloc_type>;
+
__buckets_ptr __former_buckets = nullptr;
std::size_t __former_bucket_count = _M_bucket_count;
__rehash_guard_t __rehash_guard(_M_rehash_policy);
@@ -1517,8 +1525,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   _M_element_count(__ht._M_element_count),
   _M_rehash_policy(__ht._M_rehash_policy)
 {
-  __alloc_node_gen_t __alloc_node_gen(*this);
-  _M_assign(__ht, __alloc_node_gen);
+  _M_assign(__ht);
 }
 
   template::value,
const _Hashtable&, _Hashtable&&>;
- _M_assign(std::forward<_Fwd_Ht>(__ht), __alloc_gen);
+ _M_assign(std::forward<_Fwd_Ht>(__ht));
  __ht.clear();
}
 }
diff --git a/libstdc++-v3/include/bits/hashtable_policy.h 
b/libstdc++-v3/include/bits/hashtable_policy.h
index caedb0258e

[gcc r15-5210] libstdc++: Fix calculation of system time in performance tests

2024-11-13 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:19d0720f68c2617f1b9b686d3884333b60ca75da

commit r15-5210-g19d0720f68c2617f1b9b686d3884333b60ca75da
Author: Jonathan Wakely 
Date:   Wed Nov 13 16:47:04 2024 +

libstdc++: Fix calculation of system time in performance tests

The system_time() function used the wrong element of the splits array.

Also add a comment about the units for time measurements.

libstdc++-v3/ChangeLog:

* testsuite/util/testsuite_performance.h (time_counter): Add
comment about times.
(time_counter::system_time): Use correct split value.

Diff:
---
 libstdc++-v3/testsuite/util/testsuite_performance.h | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/testsuite/util/testsuite_performance.h 
b/libstdc++-v3/testsuite/util/testsuite_performance.h
index 4fd95b7e22a7..c2be9c8e8781 100644
--- a/libstdc++-v3/testsuite/util/testsuite_performance.h
+++ b/libstdc++-v3/testsuite/util/testsuite_performance.h
@@ -73,6 +73,9 @@ namespace __gnu_test
   class time_counter
   {
   private:
+// All times are measured in clock ticks.
+// There are CLOCKS_PER_SEC ticks per second.
+// POSIX requires CLOCKS_PER_SEC == 100 so ticks == microseconds.
 clock_telapsed_begin;
 clock_telapsed_end;
 tmstms_begin;
@@ -136,7 +139,7 @@ namespace __gnu_test
 
 std::size_t
 system_time() const
-{ return (tms_end.tms_stime - tms_begin.tms_stime) + splits[1]; }
+{ return (tms_end.tms_stime - tms_begin.tms_stime) + splits[2]; }
   };
 
   class resource_counter


[gcc r15-5206] libstdc++: Fix nodiscard warnings in perf test for memory pools

2024-11-13 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:42def7cd8bab71002d3097b9db33fd1dc25a72f6

commit r15-5206-g42def7cd8bab71002d3097b9db33fd1dc25a72f6
Author: Jonathan Wakely 
Date:   Wed Nov 13 12:57:11 2024 +

libstdc++: Fix nodiscard warnings in perf test for memory pools

The use of unnamed std::lock_guard temporaries was intentional here, as
they were used like barriers (but std::barrier isn't available until
C++20). But that gives nodiscard warnings, because unnamed temporary
locks are usually unintentional. Use named variables in new block scopes
instead.

libstdc++-v3/ChangeLog:

* testsuite/performance/20_util/memory_resource/pools.cc: Fix
-Wunused-value warnings about unnamed std::lock_guard objects.

Diff:
---
 .../performance/20_util/memory_resource/pools.cc  | 15 ---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git 
a/libstdc++-v3/testsuite/performance/20_util/memory_resource/pools.cc 
b/libstdc++-v3/testsuite/performance/20_util/memory_resource/pools.cc
index 8a2a5f1facf2..5d57d1a5a0c4 100644
--- a/libstdc++-v3/testsuite/performance/20_util/memory_resource/pools.cc
+++ b/libstdc++-v3/testsuite/performance/20_util/memory_resource/pools.cc
@@ -167,7 +167,10 @@ void test_lists_resource_per_thread()
   auto run_test = [&mx] (std::pmr::memory_resource* memres,
 __gnu_test::time_counter* timers)
   {
-std::lock_guard{mx};  // block until the mutex can be locked
+{
+  // block until the mutex can be locked
+  std::lock_guard wait_for_gate_to_be_unlocked{mx};
+}
 populate_lists(memres, timers);
   };
 
@@ -239,7 +242,10 @@ void test_lists_shared_resource()
   auto run_test = [&mx] (std::pmr::memory_resource* memres,
 __gnu_test::time_counter* timers)
   {
-std::lock_guard{mx};  // block until the mutex can be locked
+{
+  // block until the mutex can be locked
+  std::lock_guard wait_for_gate_to_be_unlocked{mx};
+}
 populate_lists(memres, timers);
   };
 
@@ -307,7 +313,10 @@ void test_cross_thread_dealloc()
   [&, num_threads] (std::pmr::memory_resource* memres, int i, bool with_exit)
   {
 std::size_t counter = 0;
-std::lock_guard{mx};
+{
+  // block until the mutex can be locked
+  std::lock_guard wait_for_gate_to_be_unlocked{mx};
+}
 // Fill this thread's buffer with allocations:
 for (X& x : allocs[i])
 {


[gcc r14-10921] libstdc++: Add parentheses around operand of |

2024-11-12 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:061d18d7bd4862ff3110d497d42655efbc62ca95

commit r14-10921-g061d18d7bd4862ff3110d497d42655efbc62ca95
Author: Jonathan Wakely 
Date:   Mon Nov 11 11:23:08 2024 +

libstdc++: Add parentheses around operand of |

libstdc++-v3/ChangeLog:

* include/bits/unicode.h (_Utf_iterator::_M_read_utf16): Add
parentheses.

Diff:
---
 libstdc++-v3/include/bits/unicode.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/bits/unicode.h 
b/libstdc++-v3/include/bits/unicode.h
index a14a17c5dfcf..4b408948d722 100644
--- a/libstdc++-v3/include/bits/unicode.h
+++ b/libstdc++-v3/include/bits/unicode.h
@@ -377,7 +377,7 @@ namespace __unicode
  {
++_M_curr();
__to_incr = 2;
-   uint32_t __x = (__u & 0x3F) << 10 | __u2 & 0x3FF;
+   uint32_t __x = (__u & 0x3F) << 10 | (__u2 & 0x3FF);
uint32_t __w = (__u >> 6) & 0x1F;
__c = (__w + 1) << 16 | __x;
  }


[gcc r15-5107] libstdc++: Fix typos in iterator increment for std::text_encoding [PR117520]

2024-11-11 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:128f6a6d7af9cf187d59c1dbd9e59f5b782e17c8

commit r15-5107-g128f6a6d7af9cf187d59c1dbd9e59f5b782e17c8
Author: Jonathan Wakely 
Date:   Mon Nov 11 11:54:00 2024 +

libstdc++: Fix typos in iterator increment for std::text_encoding [PR117520]

The intended behaviour for std::text_encoding::aliases_view's iterator
is that it incrementing or decrementing too far sets it to a
value-initialized state, or fails an assertion when those are enabled.
There were typos that used == instead of = which meant that instead of
becoming singular or aborting, an out-of-range increment just did
nothing. This meant erroneous operations were well-defined and didn't
produce any undefined behaviour, but were not diagnosed with assertions
enabled, as had been intended.

This change fixes the bugs and adds more tests to verify the intended
behaviour.

libstdc++-v3/ChangeLog:

PR libstdc++/117520
* include/std/text_encoding (aliases_view:_Iterator::operator+=):
Fix typos that caused == to be used instead of =.
(aliases_view::_Iterator): Fix friend declaration.
* testsuite/std/text_encoding/members.cc: Adjust expected
behaviour of invalid subscript. Add tests for other erroneous
operations on iterators.

Diff:
---
 libstdc++-v3/include/std/text_encoding  |  6 +++---
 libstdc++-v3/testsuite/std/text_encoding/members.cc | 19 +--
 2 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/libstdc++-v3/include/std/text_encoding 
b/libstdc++-v3/include/std/text_encoding
index 48742dcb0765..6fcaed1ab6aa 100644
--- a/libstdc++-v3/include/std/text_encoding
+++ b/libstdc++-v3/include/std/text_encoding
@@ -575,7 +575,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  && _M_rep[__n - 1]._M_id == _M_id) [[likely]]
 _M_rep += __n;
  else
-   *this == _Iterator{};
+   *this = _Iterator{};
}
  else if (__n < 0)
{
@@ -583,7 +583,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
&& _M_rep[__n]._M_id == _M_id) [[likely]]
 _M_rep += __n;
  else
-   *this == _Iterator{};
+   *this = _Iterator{};
}
}
   if (__n != 0)
@@ -645,7 +645,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 }
 
   private:
-friend class text_encoding;
+friend struct text_encoding;
 
 constexpr explicit
 _Iterator(const _Rep* __r) noexcept
diff --git a/libstdc++-v3/testsuite/std/text_encoding/members.cc 
b/libstdc++-v3/testsuite/std/text_encoding/members.cc
index adbd74ab85ea..253653250c8a 100644
--- a/libstdc++-v3/testsuite/std/text_encoding/members.cc
+++ b/libstdc++-v3/testsuite/std/text_encoding/members.cc
@@ -70,10 +70,25 @@ test_every_id()
 auto end = aliases.end();
 VERIFY( (begin + std::ranges::distance(aliases)) == end );
 #ifndef _GLIBCXX_ASSERTIONS
-// This is an error, but with assertions disabled is guaranteed safe:
+// These ops violate preconditions, but as libstdc++ extensions they are
+// guaranteed to either assert or have well-defined behaviour.
+
+// This erroneously returns ""sv:
 VERIFY( begin[std::ranges::distance(aliases)] == ""sv );
 // Likewise:
-VERIFY( begin[99] == *begin );
+VERIFY( begin[99] == ""sv );
+
+auto iter = begin;
+std::ranges::advance(iter, end);
+// Erroneously sets iter to a value-initialized state.
+++iter;
+VERIFY( iter == decltype(iter){} );
+VERIFY( *iter == ""sv );
+
+iter = begin;
+// Erroneously sets iter to a value-initialized state.
+--iter;
+VERIFY( iter == decltype(iter){} );
 #endif
   }
 }


[gcc r15-5106] libstdc++: Add parentheses around operand of |

2024-11-11 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:d8992f70a59b178de85305c542eb45d1676bf0a9

commit r15-5106-gd8992f70a59b178de85305c542eb45d1676bf0a9
Author: Jonathan Wakely 
Date:   Mon Nov 11 11:23:08 2024 +

libstdc++: Add parentheses around operand of |

libstdc++-v3/ChangeLog:

* include/bits/unicode.h (_Utf_iterator::_M_read_utf16): Add
parentheses.

Diff:
---
 libstdc++-v3/include/bits/unicode.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/bits/unicode.h 
b/libstdc++-v3/include/bits/unicode.h
index d79824c3ddb1..24b1ac3d53d6 100644
--- a/libstdc++-v3/include/bits/unicode.h
+++ b/libstdc++-v3/include/bits/unicode.h
@@ -377,7 +377,7 @@ namespace __unicode
  {
++_M_curr();
__to_incr = 2;
-   uint32_t __x = (__u & 0x3F) << 10 | __u2 & 0x3FF;
+   uint32_t __x = (__u & 0x3F) << 10 | (__u2 & 0x3FF);
uint32_t __w = (__u >> 6) & 0x1F;
__c = (__w + 1) << 16 | __x;
  }


[gcc r15-5033] libstdc++: Improve comment for _Hashtable::_M_insert_unique_node

2024-11-07 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:e97179bacd067ccd3ee765632e0c034df152ccb6

commit r15-5033-ge97179bacd067ccd3ee765632e0c034df152ccb6
Author: Jonathan Wakely 
Date:   Thu Nov 7 16:51:58 2024 +

libstdc++: Improve comment for _Hashtable::_M_insert_unique_node

Clarify the effects if rehashing is needed. Document the __n_elt
parameter.

libstdc++-v3/ChangeLog:

* include/bits/hashtable.h (_M_insert_unique_node): Improve
comment.

Diff:
---
 libstdc++-v3/include/bits/hashtable.h | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/bits/hashtable.h 
b/libstdc++-v3/include/bits/hashtable.h
index bd514cab798d..6bcba2de368e 100644
--- a/libstdc++-v3/include/bits/hashtable.h
+++ b/libstdc++-v3/include/bits/hashtable.h
@@ -893,9 +893,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   pair<__node_ptr, __hash_code>
   _M_compute_hash_code(__node_ptr __hint, const key_type& __k) const;
 
-  // Insert node __n with hash code __code, in bucket __bkt if no
-  // rehash (assumes no element with same key already present).
+  // Insert node __n with hash code __code, in bucket __bkt (or another
+  // bucket if rehashing is needed).
+  // Assumes no element with equivalent key is already present.
   // Takes ownership of __n if insertion succeeds, throws otherwise.
+  // __n_elt is an estimated number of elements we expect to insert,
+  // used as a hint for rehashing when inserting a range.
   iterator
   _M_insert_unique_node(size_type __bkt, __hash_code,
__node_ptr __n, size_type __n_elt = 1);


[gcc r15-5019] libstdc++: Tweak comments on includes in hashtable headers

2024-11-07 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:6a6b8b847bce78a909379f3b9d3365c4ac4f0ff5

commit r15-5019-g6a6b8b847bce78a909379f3b9d3365c4ac4f0ff5
Author: Jonathan Wakely 
Date:   Thu Nov 7 11:14:19 2024 +

libstdc++: Tweak comments on includes in hashtable headers

std::is_permutation is only used in  not in
, so move the comment referring to it.

libstdc++-v3/ChangeLog:

* include/bits/hashtable.h: Add is_permutation to comment.
* include/bits/hashtable_policy.h: Remove it from comment.

Diff:
---
 libstdc++-v3/include/bits/hashtable.h| 2 +-
 libstdc++-v3/include/bits/hashtable_policy.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/bits/hashtable.h 
b/libstdc++-v3/include/bits/hashtable.h
index 8b312d25d7ae..d36b32a7e3fa 100644
--- a/libstdc++-v3/include/bits/hashtable.h
+++ b/libstdc++-v3/include/bits/hashtable.h
@@ -36,7 +36,7 @@
 
 #include 
 #include 
-#include  // fill_n
+#include  // fill_n, is_permutation
 #include  // __has_is_transparent_t
 #if __cplusplus > 201402L
 # include 
diff --git a/libstdc++-v3/include/bits/hashtable_policy.h 
b/libstdc++-v3/include/bits/hashtable_policy.h
index 5d79e2ba26f4..d8b201864c1a 100644
--- a/libstdc++-v3/include/bits/hashtable_policy.h
+++ b/libstdc++-v3/include/bits/hashtable_policy.h
@@ -33,7 +33,7 @@
 
 #include// for std::tuple, std::forward_as_tuple
 #include  // for __is_fast_hash
-#include  // for std::min, std::is_permutation.
+#include  // for std::min
 #include  // for std::pair
 #include // for __gnu_cxx::__aligned_buffer
 #include   // for std::__alloc_rebind


[gcc r15-4978] libstdc++: Enable debug assertions for filesystem directory iterators

2024-11-06 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:f7979b8bfa6542e6861f44c78d18cc1cf8dae4d6

commit r15-4978-gf7979b8bfa6542e6861f44c78d18cc1cf8dae4d6
Author: Jonathan Wakely 
Date:   Mon Oct 28 17:55:02 2024 +

libstdc++: Enable debug assertions for filesystem directory iterators

Several member functions of filesystem::directory_iterator and
filesystem::recursive_directory_iterator currently dereference their
shared_ptr data member without checking for non-null. Because they use
operator-> and that function only uses _GLIBCXX_DEBUG_PEDASSERT rather
than __glibcxx_assert there is no assertion even when the library is
built with _GLIBCXX_ASSERTIONS defined. This means that dereferencing
invalid directory iterators gives an unhelpful segfault.

By using (*p). instead of p-> we get an assertion when the library is
built with _GLIBCXX_ASSERTIONS, with a "_M_get() != nullptr" message.

libstdc++-v3/ChangeLog:

* src/c++17/fs_dir.cc (fs::directory_iterator::operator*): Use
shared_ptr::operator* instead of shared_ptr::operator->.
(fs::recursive_directory_iterator::options): Likewise.
(fs::recursive_directory_iterator::depth): Likewise.
(fs::recursive_directory_iterator::recursion_pending): Likewise.
(fs::recursive_directory_iterator::operator*): Likewise.
(fs::recursive_directory_iterator::disable_recursion_pending):
Likewise.

Diff:
---
 libstdc++-v3/src/c++17/fs_dir.cc | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/libstdc++-v3/src/c++17/fs_dir.cc b/libstdc++-v3/src/c++17/fs_dir.cc
index 28d27f6a9fa1..8fe9e5e4cc81 100644
--- a/libstdc++-v3/src/c++17/fs_dir.cc
+++ b/libstdc++-v3/src/c++17/fs_dir.cc
@@ -230,7 +230,7 @@ directory_iterator(const path& p, directory_options 
options, error_code* ecptr)
 const fs::directory_entry&
 fs::directory_iterator::operator*() const noexcept
 {
-  return _M_dir->entry;
+  return (*_M_dir).entry;
 }
 
 fs::directory_iterator&
@@ -327,25 +327,25 @@ 
fs::recursive_directory_iterator::~recursive_directory_iterator() = default;
 fs::directory_options
 fs::recursive_directory_iterator::options() const noexcept
 {
-  return _M_dirs->options;
+  return (*_M_dirs).options;
 }
 
 int
 fs::recursive_directory_iterator::depth() const noexcept
 {
-  return int(_M_dirs->size()) - 1;
+  return int((*_M_dirs).size()) - 1;
 }
 
 bool
 fs::recursive_directory_iterator::recursion_pending() const noexcept
 {
-  return _M_dirs->pending;
+  return (*_M_dirs).pending;
 }
 
 const fs::directory_entry&
 fs::recursive_directory_iterator::operator*() const noexcept
 {
-  return _M_dirs->top().entry;
+  return (*_M_dirs).top().entry;
 }
 
 fs::recursive_directory_iterator&
@@ -453,7 +453,7 @@ fs::recursive_directory_iterator::pop()
 void
 fs::recursive_directory_iterator::disable_recursion_pending() noexcept
 {
-  _M_dirs->pending = false;
+  (*_M_dirs).pending = false;
 }
 
 // Used to implement filesystem::remove_all.


[gcc r15-4979] libstdc++: More user-friendly failed assertions from shared_ptr dereference

2024-11-06 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:1b169ee7e25129fede3aadbeb72037017d1d5a47

commit r15-4979-g1b169ee7e25129fede3aadbeb72037017d1d5a47
Author: Jonathan Wakely 
Date:   Wed Oct 30 11:41:47 2024 +

libstdc++: More user-friendly failed assertions from shared_ptr dereference

Currently dereferencing an empty shared_ptr prints a complicated
internal type in the assertion message:

include/bits/shared_ptr_base.h:1377: std::__shared_ptr_access<_Tp, _Lp, 
,  >::element_type& std::__shared_ptr_access<_Tp, _Lp, 
,  >::operator*() const [with _Tp = 
std::filesystem::__cxx11::recursive_directory_iterator::_Dir_stack; 
__gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic; bool  = false; 
bool  = false; element_type = 
std::filesystem::__cxx11::recursive_directory_iterator::_Dir_stack]: Assertion 
'_M_get() != nullptr' failed.

Users don't care about any of the _Lp and  template
parameters, so this is unnecessarily verbose.

We can simplify it to something that only mentions "shared_ptr_deref"
and the element type:

include/bits/shared_ptr_base.h:1371: _Tp* std::__shared_ptr_deref(_Tp*) 
[with _Tp = filesystem::__cxx11::recursive_directory_iterator::_Dir_stack]: 
Assertion '__p != nullptr' failed.

libstdc++-v3/ChangeLog:

* include/bits/shared_ptr_base.h (__shared_ptr_deref): New
function template.
(__shared_ptr_access, __shared_ptr_access<>): Use it.

Diff:
---
 libstdc++-v3/include/bits/shared_ptr_base.h | 28 +---
 1 file changed, 17 insertions(+), 11 deletions(-)

diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h 
b/libstdc++-v3/include/bits/shared_ptr_base.h
index 9a7617e7014f..ee01594ce0c5 100644
--- a/libstdc++-v3/include/bits/shared_ptr_base.h
+++ b/libstdc++-v3/include/bits/shared_ptr_base.h
@@ -1337,6 +1337,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { };
 
 
+  template
+[[__gnu__::__always_inline__]]
+inline _Tp*
+__shared_ptr_deref(_Tp* __p)
+{
+  __glibcxx_assert(__p != nullptr);
+  return __p;
+}
+
   // Define operator* and operator-> for shared_ptr.
   template::value, bool = is_void<_Tp>::value>
@@ -1347,10 +1356,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   element_type&
   operator*() const noexcept
-  {
-   __glibcxx_assert(_M_get() != nullptr);
-   return *_M_get();
-  }
+  { return *std::__shared_ptr_deref(_M_get()); }
 
   element_type*
   operator->() const noexcept
@@ -1392,10 +1398,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   [[__deprecated__("shared_ptr::operator* is absent from C++17")]]
   element_type&
   operator*() const noexcept
-  {
-   __glibcxx_assert(_M_get() != nullptr);
-   return *_M_get();
-  }
+  { return *std::__shared_ptr_deref(_M_get()); }
 
   [[__deprecated__("shared_ptr::operator-> is absent from C++17")]]
   element_type*
@@ -1406,13 +1409,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   }
 #endif
 
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wc++17-extensions"
   element_type&
   operator[](ptrdiff_t __i) const noexcept
   {
-   __glibcxx_assert(_M_get() != nullptr);
-   __glibcxx_assert(!extent<_Tp>::value || __i < extent<_Tp>::value);
-   return _M_get()[__i];
+   if constexpr (extent<_Tp>::value)
+ __glibcxx_assert(__i < extent<_Tp>::value);
+   return std::__shared_ptr_deref(_M_get())[__i];
   }
+#pragma GCC diagnostic pop
 
 private:
   element_type*


[gcc r15-4855] libstdc++: Check feature test macros in unordered containers

2024-11-01 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:1a5bdeb1128ecfa4ce233218d02ccbb88ce0d8a8

commit r15-4855-g1a5bdeb1128ecfa4ce233218d02ccbb88ce0d8a8
Author: Jonathan Wakely 
Date:   Fri Nov 1 10:50:02 2024 +

libstdc++: Check feature test macros in unordered containers

Replace some `__cplusplus > 201402L` preprocessor checks with more
expressive checks for the appropriate feature test macros.

libstdc++-v3/ChangeLog:

* include/bits/unordered_map.h: Check __glibcxx_node_extract and
__glibcxx_unordered_map_try_emplace instead of __cplusplus.
* include/bits/unordered_set.h: Check __glibcxx_node_extract
instead of __cplusplus.

Diff:
---
 libstdc++-v3/include/bits/unordered_map.h | 28 ++--
 libstdc++-v3/include/bits/unordered_set.h | 24 
 2 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/libstdc++-v3/include/bits/unordered_map.h 
b/libstdc++-v3/include/bits/unordered_map.h
index 8607944d5653..3b472534c660 100644
--- a/libstdc++-v3/include/bits/unordered_map.h
+++ b/libstdc++-v3/include/bits/unordered_map.h
@@ -137,7 +137,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
   typedef typename _Hashtable::difference_type difference_type;
   ///@}
 
-#if __cplusplus > 201402L
+#ifdef __glibcxx_node_extract // >= C++17 && HOSTED
   using node_type = typename _Hashtable::node_type;
   using insert_return_type = typename _Hashtable::insert_return_type;
 #endif
@@ -426,7 +426,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
emplace_hint(const_iterator __pos, _Args&&... __args)
{ return _M_h.emplace_hint(__pos, std::forward<_Args>(__args)...); }
 
-#if __cplusplus > 201402L
+#ifdef __glibcxx_node_extract // >= C++17 && HOSTED
   /// Extract a node.
   node_type
   extract(const_iterator __pos)
@@ -449,7 +449,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
   iterator
   insert(const_iterator, node_type&& __nh)
   { return _M_h._M_reinsert_node(std::move(__nh)).position; }
-#endif // C++17
+#endif // node_extract
 
 #ifdef __glibcxx_unordered_map_try_emplace // C++ >= 17 && HOSTED
   /**
@@ -636,7 +636,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
   { _M_h.insert(__l); }
 
 
-#if __cplusplus > 201402L
+#ifdef __glibcxx_unordered_map_try_emplace // >= C++17 && HOSTED
   /**
*  @brief Attempts to insert a std::pair into the %unordered_map.
*  @param __kKey to use for finding a possibly existing pair in
@@ -728,7 +728,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
__ret.first->second = std::forward<_Obj>(__obj);
  return __ret.first;
}
-#endif
+#endif // unordered_map_try_emplace
 
   ///@{
   /**
@@ -813,7 +813,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
   noexcept( noexcept(_M_h.swap(__x._M_h)) )
   { _M_h.swap(__x._M_h); }
 
-#if __cplusplus > 201402L
+#ifdef __glibcxx_node_extract // >= C++17 && HOSTED
   template
friend class std::_Hash_merge_helper;
 
@@ -842,7 +842,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
void
merge(unordered_multimap<_Key, _Tp, _H2, _P2, _Alloc>&& __source)
{ merge(__source); }
-#endif // C++17
+#endif // node_extract
 
   // observers.
 
@@ -1283,7 +1283,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
   typedef typename _Hashtable::difference_type difference_type;
   ///@}
 
-#if __cplusplus > 201402L
+#ifdef __glibcxx_node_extract // >= C++17 && HOSTED
   using node_type = typename _Hashtable::node_type;
 #endif
 
@@ -1648,7 +1648,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
   insert(initializer_list __l)
   { _M_h.insert(__l); }
 
-#if __cplusplus > 201402L
+#ifdef __glibcxx_node_extract // >= C++17 && HOSTED
   /// Extract a node.
   node_type
   extract(const_iterator __pos)
@@ -1671,7 +1671,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
   iterator
   insert(const_iterator __hint, node_type&& __nh)
   { return _M_h._M_reinsert_node_multi(__hint, std::move(__nh)); }
-#endif // C++17
+#endif // node_extract
 
   ///@{
   /**
@@ -1756,7 +1756,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
   noexcept( noexcept(_M_h.swap(__x._M_h)) )
   { _M_h.swap(__x._M_h); }
 
-#if __cplusplus > 201402L
+#ifdef __glibcxx_node_extract // >= C++17 && HOSTED
   template
friend class std::_Hash_merge_helper;
 
@@ -1787,7 +1787,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
void
merge(unordered_map<_Key, _Tp, _H2, _P2, _Alloc>&& __source)
{ merge(__source); }
-#endif // C++17
+#endif // node_extract
 
   // observers.
 
@@ -2169,7 +2169,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 
 _GLIBCXX_END_NAMESPACE_CONTAINER
 
-#if __cplusplus > 201402L
+#ifdef __glibcxx_node_extract // >= C++17 && HOSTED
   // Allow std::unordered_map access to internals of compatible maps.
   template
@@ -2217,7 +2217,7 @@ _GLIBCXX_END_NAMESPACE_CONTAINER
   _S_get_table(unordered_multimap<_Key, _Val, _Hash2, _Eq2, _Alloc>&

[gcc r15-4854] libstdc++: Minor comment improvements in

2024-11-01 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:db798ee38a3f81eff207e889c36c727bb370112c

commit r15-4854-gdb798ee38a3f81eff207e889c36c727bb370112c
Author: Jonathan Wakely 
Date:   Fri Nov 1 12:46:26 2024 +

libstdc++: Minor comment improvements in 

libstdc++-v3/ChangeLog:

* include/bits/hashtable.h: Improve comments.

Diff:
---
 libstdc++-v3/include/bits/hashtable.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/bits/hashtable.h 
b/libstdc++-v3/include/bits/hashtable.h
index f1a5490b5ff3..47321a9cb135 100644
--- a/libstdc++-v3/include/bits/hashtable.h
+++ b/libstdc++-v3/include/bits/hashtable.h
@@ -1019,7 +1019,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   iterator
   erase(const_iterator);
 
-  // LWG 2059.
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // 2059. C++0x ambiguity problem with map::erase
   iterator
   erase(iterator __it)
   { return erase(const_iterator(__it)); }
@@ -1041,7 +1042,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // DR 1189.
   // reserve, if present, comes from _Rehash_base.
 
-#if __glibcxx_node_extract // >= C++17
+#if __glibcxx_node_extract // >= C++17 && HOSTED
   /// Re-insert an extracted node into a container with unique keys.
   insert_return_type
   _M_reinsert_node(node_type&& __nh)


[gcc r15-4839] libstdc++: Add missing header to unordered_set/pr115285.cc test

2024-11-01 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:a51d220377ab8117305567e888a942d127ef6a48

commit r15-4839-ga51d220377ab8117305567e888a942d127ef6a48
Author: Jonathan Wakely 
Date:   Fri Nov 1 16:09:02 2024 +

libstdc++: Add missing  header to unordered_set/pr115285.cc test

libstdc++-v3/ChangeLog:

* testsuite/23_containers/unordered_set/pr115285.cc: Include
missing header for std::vector.

Diff:
---
 libstdc++-v3/testsuite/23_containers/unordered_set/pr115285.cc | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/pr115285.cc 
b/libstdc++-v3/testsuite/23_containers/unordered_set/pr115285.cc
index 6c5cc24930ce..85954aed74b5 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_set/pr115285.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/pr115285.cc
@@ -2,8 +2,9 @@
 
 // libstdc++/115285
 
-#include 
 #include 
+#include 
+#include 
 
 #include 


[gcc r15-4838] libstdc++: Remove stray whitespace in #endif

2024-11-01 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:063196e3933ddbe6c662f4996f68567d348a99f1

commit r15-4838-g063196e3933ddbe6c662f4996f68567d348a99f1
Author: Jonathan Wakely 
Date:   Fri Nov 1 12:25:07 2024 +

libstdc++: Remove stray whitespace in #endif

This isn't nested within another #if group so shouldn't be indented like
this.

libstdc++-v3/ChangeLog:

* libsupc++/typeinfo: Remove whitespace in #endif

Diff:
---
 libstdc++-v3/libsupc++/typeinfo | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/libsupc++/typeinfo b/libstdc++-v3/libsupc++/typeinfo
index 71066eb1e465..721268cb3fa3 100644
--- a/libstdc++-v3/libsupc++/typeinfo
+++ b/libstdc++-v3/libsupc++/typeinfo
@@ -212,7 +212,7 @@ namespace std
 return false;
 #endif
   }
-# endif
+#endif
 
 
   /**


[gcc r15-4789] libstdc++: Fix copy&paste comments in vector range tests

2024-10-30 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:5e26a340b228caac04d5c33bceae0a5b7861d1b7

commit r15-4789-g5e26a340b228caac04d5c33bceae0a5b7861d1b7
Author: Jonathan Wakely 
Date:   Wed Oct 30 19:27:54 2024 +

libstdc++: Fix copy&paste comments in vector range tests

These comments were copied from the std::vector tests, but the
value_type is not bool in these ones.

libstdc++-v3/ChangeLog:

* testsuite/23_containers/vector/cons/from_range.cc: Fix copy &
paste error in comment.
* testsuite/23_containers/vector/modifiers/append_range.cc:
Likewise.
* testsuite/23_containers/vector/modifiers/assign/assign_range.cc:
Likewise.
* testsuite/23_containers/vector/modifiers/insert/insert_range.cc:
Likewise.

Diff:
---
 libstdc++-v3/testsuite/23_containers/vector/cons/from_range.cc  | 2 +-
 libstdc++-v3/testsuite/23_containers/vector/modifiers/append_range.cc   | 2 +-
 .../testsuite/23_containers/vector/modifiers/assign/assign_range.cc | 2 +-
 .../testsuite/23_containers/vector/modifiers/insert/insert_range.cc | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/libstdc++-v3/testsuite/23_containers/vector/cons/from_range.cc 
b/libstdc++-v3/testsuite/23_containers/vector/cons/from_range.cc
index e91465f5a711..ed2e3ca6ba1e 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/cons/from_range.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/cons/from_range.cc
@@ -80,7 +80,7 @@ test_ranges()
   do_test_a>();
   do_test_a>();
 
-  // Not lvalue-convertible to bool
+  // Not lvalue-convertible to int
   struct C {
 C(int v) : val(v) { }
 operator int() && { return val; }
diff --git 
a/libstdc++-v3/testsuite/23_containers/vector/modifiers/append_range.cc 
b/libstdc++-v3/testsuite/23_containers/vector/modifiers/append_range.cc
index 24a5c7d0e7cc..5725cd2ad483 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/modifiers/append_range.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/modifiers/append_range.cc
@@ -69,7 +69,7 @@ test_ranges()
   do_test_a>();
   do_test_a>();
 
-  // Not lvalue-convertible to bool
+  // Not lvalue-convertible to int
   struct C {
 C(int v) : val(v) { }
 operator int() && { return val; }
diff --git 
a/libstdc++-v3/testsuite/23_containers/vector/modifiers/assign/assign_range.cc 
b/libstdc++-v3/testsuite/23_containers/vector/modifiers/assign/assign_range.cc
index 4e8d8af1614a..db3b06cfbc06 100644
--- 
a/libstdc++-v3/testsuite/23_containers/vector/modifiers/assign/assign_range.cc
+++ 
b/libstdc++-v3/testsuite/23_containers/vector/modifiers/assign/assign_range.cc
@@ -90,7 +90,7 @@ test_ranges()
   do_test_a>();
   do_test_a>();
 
-  // Not lvalue-convertible to bool
+  // Not lvalue-convertible to int
   struct C {
 C(int v) : val(v) { }
 operator int() && { return val; }
diff --git 
a/libstdc++-v3/testsuite/23_containers/vector/modifiers/insert/insert_range.cc 
b/libstdc++-v3/testsuite/23_containers/vector/modifiers/insert/insert_range.cc
index 30219f5da02f..68218e94f28b 100644
--- 
a/libstdc++-v3/testsuite/23_containers/vector/modifiers/insert/insert_range.cc
+++ 
b/libstdc++-v3/testsuite/23_containers/vector/modifiers/insert/insert_range.cc
@@ -80,7 +80,7 @@ test_ranges()
   do_test_a>();
   do_test_a>();
 
-  // Not lvalue-convertible to bool
+  // Not lvalue-convertible to int
   struct C {
 C(int v) : val(v) { }
 operator int() && { return val; }


[gcc r15-4777] libstdc++: Define config macros for additional IEEE formats

2024-10-30 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:e2692b9ea7bde28de2a31a3580ce9dcc25e42fa4

commit r15-4777-ge2692b9ea7bde28de2a31a3580ce9dcc25e42fa4
Author: Jonathan Wakely 
Date:   Thu Oct 24 11:40:42 2024 +0100

libstdc++: Define config macros for additional IEEE formats

Some targets use IEEE binary64 for both double and long double, which
means we could use memmove to optimize a std::copy from a range of
double to a range of long double. We currently have no config macro to
detect when long double is binary64, so add that to .

This also adds config macros for the case where double and long double
both use the same binary32 format as float, which is true for the avr
target. No specializations of __memcpyable for that case are added by
this patch, but they could be added later.

libstdc++-v3/ChangeLog:

* include/bits/c++config (_GLIBCXX_DOUBLE_IS_IEEE_BINARY32):
Define.
(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY64): Define.
(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY32): Define.
* include/bits/cpp_type_traits.h (__memcpyable): Define
specializations when double and long double are compatible.

Reviewed-by: Patrick Palka 

Diff:
---
 libstdc++-v3/include/bits/c++config | 21 ++---
 libstdc++-v3/include/bits/cpp_type_traits.h |  7 +++
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/libstdc++-v3/include/bits/c++config 
b/libstdc++-v3/include/bits/c++config
index b87a3527f24b..1076803a8655 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -836,25 +836,40 @@ namespace std
 # endif
 #endif
 
-// Define if float has the IEEE binary32 format.
 #if __FLT_MANT_DIG__ == 24 \
   && __FLT_MIN_EXP__ == -125 \
   && __FLT_MAX_EXP__ == 128
+// Define if float has the IEEE binary32 format.
 # define _GLIBCXX_FLOAT_IS_IEEE_BINARY32 1
 #endif
 
-// Define if double has the IEEE binary64 format.
 #if __DBL_MANT_DIG__ == 53 \
   && __DBL_MIN_EXP__ == -1021 \
   && __DBL_MAX_EXP__ == 1024
+// Define if double has the IEEE binary64 format.
 # define _GLIBCXX_DOUBLE_IS_IEEE_BINARY64 1
+#elif __FLT_MANT_DIG__ == 24 \
+  && __FLT_MIN_EXP__ == -125 \
+  && __FLT_MAX_EXP__ == 128
+// Define if double has the IEEE binary32 format.
+# define _GLIBCXX_DOUBLE_IS_IEEE_BINARY32 1
 #endif
 
-// Define if long double has the IEEE binary128 format.
 #if __LDBL_MANT_DIG__ == 113 \
   && __LDBL_MIN_EXP__ == -16381 \
   && __LDBL_MAX_EXP__ == 16384
+// Define if long double has the IEEE binary128 format.
 # define _GLIBCXX_LDOUBLE_IS_IEEE_BINARY128 1
+#elif __LDBL_MANT_DIG__ == 53 \
+  && __LDBL_MIN_EXP__ == -1021 \
+  && __LDBL_MAX_EXP__ == 1024
+// Define if long double has the IEEE binary64 format.
+# define _GLIBCXX_LDOUBLE_IS_IEEE_BINARY64 1
+#elif __LDBL_MANT_DIG__ == 24 \
+  && __LDBL_MIN_EXP__ == -125 \
+  && __LDBL_MAX_EXP__ == 128
+// Define if long double has the IEEE binary32 format.
+# define _GLIBCXX_LDOUBLE_IS_IEEE_BINARY32 1
 #endif
 
 #if defined __cplusplus && defined __BFLT16_DIG__
diff --git a/libstdc++-v3/include/bits/cpp_type_traits.h 
b/libstdc++-v3/include/bits/cpp_type_traits.h
index e412f8d07703..e5a5efece42d 100644
--- a/libstdc++-v3/include/bits/cpp_type_traits.h
+++ b/libstdc++-v3/include/bits/cpp_type_traits.h
@@ -556,6 +556,13 @@ __INT_N(__GLIBCXX_TYPE_INT_N_3)
 struct __memcpyable_integer { enum { __width = 128 }; };
 #endif
 
+#if _GLIBCXX_DOUBLE_IS_IEEE_BINARY64 && _GLIBCXX_LDOUBLE_IS_IEEE_BINARY64
+  template<>
+struct __memcpyable { enum { __value = true }; };
+  template<>
+struct __memcpyable { enum { __value = true }; };
+#endif
+
 #if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
   template<>
 struct __memcpyable<_Float32*, float*> { enum { __value = true }; };


[gcc r15-4720] libstdc++: Fix tests for std::vector range operations

2024-10-28 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:e320846fec00aaa3ca1f93790bc41dbc08503814

commit r15-4720-ge320846fec00aaa3ca1f93790bc41dbc08503814
Author: Jonathan Wakely 
Date:   Mon Oct 28 13:05:53 2024 +

libstdc++: Fix tests for std::vector range operations

The commit I pushed was not the one I'd tested, so it had older versions
of the tests, with bugs that I'd already fixed locally. This commit has
the fixed tests that I'd intended to push in the first place.

libstdc++-v3/ChangeLog:

* testsuite/23_containers/vector/bool/cons/from_range.cc: Use
dg-do run instead of compile.
(test_ranges): Use do_test instead of do_test_a for rvalue
range.
(test_constexpr): Call function template instead of just
instantiating it.
* 
testsuite/23_containers/vector/bool/modifiers/assign/assign_range.cc:
Use dg-do run instead of compile.
(do_test): Use same test logic for vector as for primary
template.
(test_constexpr): Call function template instead of just
instantiating it.
* 
testsuite/23_containers/vector/bool/modifiers/insert/append_range.cc:
Use dg-do run instead of compile.
(test_ranges): Use do_test instead of do_test_a for rvalue
range.
(test_constexpr): Call function template instead of just
instantiating it.
* 
testsuite/23_containers/vector/bool/modifiers/insert/insert_range.cc:
Use dg-do run instead of compile.
(do_test): Fix incorrect function arguments to match intended
results.
(test_ranges): Use do_test instead of do_test_a for rvalue
range.
(test_constexpr): Call function template instead of just
instantiating it.
* testsuite/23_containers/vector/cons/from_range.cc: Use dg-do
run instead of compile.
(test_ranges): Fix ill-formed call to do_test.
(test_constexpr): Call function template instead of just
instantiating it.
* testsuite/23_containers/vector/modifiers/append_range.cc:
Use dg-do run instead of compile.
(test_constexpr): Likewise.
* testsuite/23_containers/vector/modifiers/assign/assign_range.cc:
Use dg-do run instead of compile.
(do_test): Do not reuse input ranges.
(test_constexpr): Call function template instead of just
instantiating it.
* testsuite/23_containers/vector/modifiers/insert/insert_range.cc:
Use dg-do run instead of compile.
(do_test): Fix incorrect function arguments to match intended
results.
(test_constexpr): Call function template instead of just
instantiating it.

Diff:
---
 .../23_containers/vector/bool/cons/from_range.cc   |  6 ++---
 .../vector/bool/modifiers/assign/assign_range.cc   | 30 ++
 .../vector/bool/modifiers/insert/append_range.cc   |  6 ++---
 .../vector/bool/modifiers/insert/insert_range.cc   | 10 
 .../23_containers/vector/cons/from_range.cc|  6 ++---
 .../23_containers/vector/modifiers/append_range.cc |  4 +--
 .../vector/modifiers/assign/assign_range.cc| 25 --
 .../vector/modifiers/insert/insert_range.cc|  8 +++---
 8 files changed, 50 insertions(+), 45 deletions(-)

diff --git 
a/libstdc++-v3/testsuite/23_containers/vector/bool/cons/from_range.cc 
b/libstdc++-v3/testsuite/23_containers/vector/bool/cons/from_range.cc
index f5180e5a2433..f531e7f50396 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/bool/cons/from_range.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/bool/cons/from_range.cc
@@ -1,4 +1,4 @@
-// { dg-do compile { target c++23 } }
+// { dg-do run { target c++23 } }
 
 #include 
 #include 
@@ -71,7 +71,7 @@ test_ranges()
 bool val;
   };
   using rvalue_input_range = test_range;
-  do_test_a();
+  do_test(std::allocator());
 
   return true;
 }
@@ -80,7 +80,7 @@ constexpr bool
 test_constexpr()
 {
   // XXX: this doesn't test the non-forward_range code paths are constexpr.
-  do_test, std::allocator>;
+  do_test>(std::allocator());
   return true;
 }
 
diff --git 
a/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/assign/assign_range.cc
 
b/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/assign/assign_range.cc
index a014dfe90de7..7e58700ff2bb 100644
--- 
a/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/assign/assign_range.cc
+++ 
b/libstdc++-v3/testsuite/23_containers/vector/bool/modifiers/assign/assign_range.cc
@@ -1,4 +1,4 @@
-// { dg-do compile { target c++23 } }
+// { dg-do run { target c++23 } }
 
 #include 
 #include 
@@ -22,29 +22,37 @@ do_test()
 return true;
   };
 
-  Range r4(a, a+4);
-  Range r9(a);
-
+  // assign to empty vector
   std::vector v;
   v.assign_range(Range(a,

[gcc r15-4708] libstdc++: Fix std::vector::emplace to forward parameter

2024-10-27 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:f1c844be5202f4be446f165d9a7625eb7ec4c5b4

commit r15-4708-gf1c844be5202f4be446f165d9a7625eb7ec4c5b4
Author: Jonathan Wakely 
Date:   Sat Oct 26 21:24:58 2024 +0100

libstdc++: Fix std::vector::emplace to forward parameter

If the parameter is not lvalue-convertible to bool then the current code
will fail to compile. The parameter should be forwarded to restore the
original value category.

libstdc++-v3/ChangeLog:

* include/bits/stl_bvector.h (emplace_back, emplace): Forward
parameter pack to preserve value category.
* testsuite/23_containers/vector/bool/emplace_rvalue.cc: New
test.

Diff:
---
 libstdc++-v3/include/bits/stl_bvector.h|  4 ++--
 .../23_containers/vector/bool/emplace_rvalue.cc| 24 ++
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/bits/stl_bvector.h 
b/libstdc++-v3/include/bits/stl_bvector.h
index 42261ac5915f..70f69b5b5b55 100644
--- a/libstdc++-v3/include/bits/stl_bvector.h
+++ b/libstdc++-v3/include/bits/stl_bvector.h
@@ -1343,7 +1343,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 #endif
emplace_back(_Args&&... __args)
{
- push_back(bool(__args...));
+ push_back(bool(std::forward<_Args>(__args)...));
 #if __cplusplus > 201402L
  return back();
 #endif
@@ -1353,7 +1353,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_GLIBCXX20_CONSTEXPR
iterator
emplace(const_iterator __pos, _Args&&... __args)
-   { return insert(__pos, bool(__args...)); }
+   { return insert(__pos, bool(std::forward<_Args>(__args)...)); }
 #endif
 
 protected:
diff --git a/libstdc++-v3/testsuite/23_containers/vector/bool/emplace_rvalue.cc 
b/libstdc++-v3/testsuite/23_containers/vector/bool/emplace_rvalue.cc
new file mode 100644
index ..5dea2426d602
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/bool/emplace_rvalue.cc
@@ -0,0 +1,24 @@
+// { dg-do compile { target c++11 } }
+
+#include 
+
+struct S
+{
+  explicit operator bool() &&;
+};
+
+void
+test_emplace_back()
+{
+  S s;
+  std::vector v;
+  v.emplace_back(std::move(s));
+}
+
+void
+test_emplace()
+{
+  S s;
+  std::vector v;
+  v.emplace(v.begin(), std::move(s));
+}


[gcc r15-4666] libstdc++: Disable parts of new test that depend on constexpr std::string

2024-10-25 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:a4931587cbccdb6aff352f9df728ab468c5260b9

commit r15-4666-ga4931587cbccdb6aff352f9df728ab468c5260b9
Author: Jonathan Wakely 
Date:   Thu Oct 24 20:12:08 2024 +0100

libstdc++: Disable parts of new test that depend on constexpr std::string

The compile-time assertions don't work with -D_GLIBCXX_USE_CXX11_ABI=0.

libstdc++-v3/ChangeLog:

* 
testsuite/21_strings/basic_string/operators/char/op_plus_string_view.cc:
Check __cpp_lib_constexpr_string.

Diff:
---
 .../21_strings/basic_string/operators/char/op_plus_string_view.cc   | 2 ++
 1 file changed, 2 insertions(+)

diff --git 
a/libstdc++-v3/testsuite/21_strings/basic_string/operators/char/op_plus_string_view.cc
 
b/libstdc++-v3/testsuite/21_strings/basic_string/operators/char/op_plus_string_view.cc
index 364d5bd5abab..2d474519f60a 100644
--- 
a/libstdc++-v3/testsuite/21_strings/basic_string/operators/char/op_plus_string_view.cc
+++ 
b/libstdc++-v3/testsuite/21_strings/basic_string/operators/char/op_plus_string_view.cc
@@ -44,6 +44,7 @@ struct convertible_to_lots
   constexpr operator std::string() const { return "convertible_to_lots3"; }
 };
 
+#if __cpp_lib_constexpr_string >= 201907 // constexpr std::string
 using namespace std::literals;
 static_assert( "costa "s + "marbella"sv == "costa marbella"s );
 static_assert( "costa "sv + "marbella"s == "costa marbella"s );
@@ -52,6 +53,7 @@ static_assert( "costa "s + convertible_to_string_view2{} == 
"costa convertible_t
 static_assert( "costa "s + convertible_to_string_view3{} == "costa 
convertible_to_sv3 non_const"s );
 static_assert( "costa "s + convertible_to_string_view_and_char_star{} == 
"costa convertible_to_sv_and_charstar1"s );
 static_assert( "costa "s + convertible_to_lots{} == "costa 
convertible_to_lots1"s );
+#endif // __cpp_lib_constexpr_string
 
 void
 test01()


[gcc r15-4581] top-level: Add pull request template for Forgejo

2024-10-23 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:f342d66d6990b9559dde13e616a2921a7bfae176

commit r15-4581-gf342d66d6990b9559dde13e616a2921a7bfae176
Author: Jonathan Wakely 
Date:   Wed Oct 23 15:20:27 2024 +0100

top-level: Add pull request template for Forgejo

ChangeLog:

* .forgejo/PULL_REQUEST_TEMPLATE.md: New file.

Diff:
---
 .forgejo/PULL_REQUEST_TEMPLATE.md | 9 +
 1 file changed, 9 insertions(+)

diff --git a/.forgejo/PULL_REQUEST_TEMPLATE.md 
b/.forgejo/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index ..fc645f11305c
--- /dev/null
+++ b/.forgejo/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,9 @@
+Thanks for taking the time to contribute to GCC!
+
+Please be advised that https://forge.sourceware.org/ is currently a trial
+that is being used by the GCC community to experiment with a new workflow
+based on pull requests.
+
+Pull requests sent here may be forgotten or ignored. Patches that you want to
+propose for inclusion in GCC should use the existing email-based workflow,
+see https://gcc.gnu.org/contribute.html


[gcc r15-4577] libstdc++: Add -D_GLIBCXX_ASSERTIONS default for -O0 to API history

2024-10-23 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:4b0f238855f8fa79acf7cca84b523ca8513bf68d

commit r15-4577-g4b0f238855f8fa79acf7cca84b523ca8513bf68d
Author: Jonathan Wakely 
Date:   Wed Oct 23 16:01:04 2024 +0100

libstdc++: Add -D_GLIBCXX_ASSERTIONS default for -O0 to API history

libstdc++-v3/ChangeLog:

* doc/xml/manual/evolution.xml: Document that assertions are
enabled for unoptimized builds.
* doc/html/*: Regenerate.

Diff:
---
 libstdc++-v3/doc/html/index.html   | 2 +-
 libstdc++-v3/doc/html/manual/api.html  | 2 ++
 libstdc++-v3/doc/html/manual/appendix.html | 2 +-
 libstdc++-v3/doc/html/manual/appendix_porting.html | 2 +-
 libstdc++-v3/doc/html/manual/index.html| 2 +-
 libstdc++-v3/doc/xml/manual/evolution.xml  | 8 
 6 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/libstdc++-v3/doc/html/index.html b/libstdc++-v3/doc/html/index.html
index 395908f17a1a..e96f2cb27047 100644
--- a/libstdc++-v3/doc/html/index.html
+++ b/libstdc++-v3/doc/html/index.html
@@ -142,7 +142,7 @@
 Existing tests
 
 C++11 Requirements Test Sequence Descriptions
-ABI Policy and 
GuidelinesThe C++ 
InterfaceVersioningGoalsHistoryPrerequisitesConfiguringChecking 
ActiveAllowed 
ChangesProhibited ChangesImplementationTestingSingle ABI 
TestingMultiple ABI 
TestingOutstanding 
IssuesAPI Evolution and Deprecation 
History3.03.13.23.33.44.04.14.24.34.44.54.64.74.84.955.3677.27.38910111212.31313.3class="constant">14class="section">Backwards 
 >Compatibilityhref="manual/backwards.html#backwards.first">Firstclass="section">href="manual/backwards.html#backwards.second">Secondclass="section">href="manual/backwards.html#backwards.third">Third class="section">href="manual/backwards.html#backwards.third.headers">Pre-ISO headers 
 >removedhref="manual/backwards.html#backwards.third.hash">Extension headers hash_map, 
 >hash_set moved to ext or backwardsclass="section">href="manual/backwards.html#backwards.third.nocreate_noreplace">No class="code">ios::nocreate/ios::noreplace.
+ABI Policy and 
GuidelinesThe C++ 
InterfaceVersioningGoalsHistoryPrerequisitesConfiguringChecking 
ActiveAllowed 
ChangesProhibited ChangesImplementationTestingSingle ABI 
TestingMultiple ABI 
TestingOutstanding 
IssuesAPI Evolution and Deprecation 
History3.03.13.23.33.44.04.14.24.34.44.54.64.74.84.955.3677.27.38910111212.31313.3class="constant">14href="manual/api.html#api.rel_151">class="constant">15class="section">Backwards 
 >Compatibilityhref="manual/backwards.html#backwards.first">Firstclass="section">href="manual/backwards.html#backwards.second">Secondclass="section">href="manual/backwards.html#backwards.third">Third class="section">href="manual/backwards.html#backwards.third.headers">Pre-ISO headers 
 >removedhref="manual/backwards.html#backwards.third.hash">Extension headers hash_map, 
 >hash_set moved to ext or backwardsclass="section">No ios::nocreate/ios::noreplace.
 
 No stream::attach(int fd)
 
diff --git a/libstdc++-v3/doc/html/manual/api.html 
b/libstdc++-v3/doc/html/manual/api.html
index 59ed4c888628..799f6eae2a23 100644
--- a/libstdc++-v3/doc/html/manual/api.html
+++ b/libstdc++-v3/doc/html/manual/api.html
@@ -496,4 +496,6 @@ to be used with std::basic_istream.
   The extension allowing std::basic_string to be 
instantiated
   with an allocator that doesn't match the string's character type is no
   longer allowed in C++20 mode.
+15
+Enabled debug assertions by default for unoptimized builds.
 Prev Up NextABI Policy and Guidelines Home Backwards 
Compatibility
\ No newline at end of file
diff --git a/libstdc++-v3/doc/html/manual/appendix.html 
b/libstdc++-v3/doc/html/manual/appendix.html
index affd5839f435..69a0e0018f37 100644
--- a/libstdc++-v3/doc/html/manual/appendix.html
+++ b/libstdc++-v3/doc/html/manual/appendix.html
@@ -16,7 +16,7 @@
 Existing tests
 
 C++11 Requirements Test Sequence Descriptions
-ABI Policy and GuidelinesThe C++ 
InterfaceVersioningGoalsHistoryPrerequisitesConfiguringChecking 
ActiveAllowed ChangesProhibited 
Changes<
 dt>ImplementationTestingSingle ABI 
TestingMultiple ABI 
TestingOutstanding 
IssuesAPI Evolution and Deprecation 
History3.03.13.23.3<
 /span>3.44.04.14.24.34.44.54.64.74.84.955.3677.27.38910111212.31313.314Backwards 
CompatibilityFirstSecondThirdPre-ISO 
headers removedExtension headers hash_map, hash_set 
moved to ext or backwardsNo ios::nocreate/ios::noreplace.
+ABI Policy and GuidelinesThe C++ 
InterfaceVersioningGoalsHistoryPrerequisitesConfiguringChecking 
ActiveAllowed ChangesProhibited 
Changes<
 dt>ImplementationTestingSingle ABI 
TestingMultiple ABI 
TestingOutstanding 
IssuesAPI Evolution and Deprecation 
History3.03.13.23.3<
 /span>3.44.04.14.24.34.44.54.64.74.84.955.3677.27.38910111212.31313.31415Backwards 
Compatibility
 FirstSecondThirdPre-ISO 
headers removedExtension headers hash_map, hash_set 
moved to ext or backwardsNo ios::nocreate/ios::noreplace.
 
 No stream::attach(int fd)
 
diff 

[gcc r15-4576] libstdc++: Add GLIBCXX_TESTSUITE_STDS example to docs

2024-10-23 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:5a661ecdfb22dd6fd1524ee8619be4bc046a1b2a

commit r15-4576-g5a661ecdfb22dd6fd1524ee8619be4bc046a1b2a
Author: Jonathan Wakely 
Date:   Tue Oct 22 21:18:51 2024 +0100

libstdc++: Add GLIBCXX_TESTSUITE_STDS example to docs

libstdc++-v3/ChangeLog:

* doc/xml/manual/test.xml: Add GLIBCXX_TESTSUITE_STDS example.
* doc/html/manual/test.html: Regenerate.

Diff:
---
 libstdc++-v3/doc/html/manual/test.html | 5 +++--
 libstdc++-v3/doc/xml/manual/test.xml   | 5 +++--
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/libstdc++-v3/doc/html/manual/test.html 
b/libstdc++-v3/doc/html/manual/test.html
index 3657997fad46..1c7af1193daf 100644
--- a/libstdc++-v3/doc/html/manual/test.html
+++ b/libstdc++-v3/doc/html/manual/test.html
@@ -352,12 +352,13 @@ cat 27_io/objects/char/3_xin.in | 
a.out-std, similar to 
the G++ tests.
   Adding set v3_std_list { 11 17 23 } to
-  ~/.dejagnurc or a file named by the
+  ~/.dejagnurc or to a file named by the
   DEJAGNU environment variable will cause every 
test to
   be run three times, using a different -std 
each time.
   Alternatively, a list of standard versions to test with can be specified
   as a comma-separated list in the GLIBCXX_TESTSUITE_STDS
-  environment variable.
+  environment variable, e.g. GLIBCXX_TESTSUITE_STDS=11,17,23
+  is equivalent to the v3_std_list value above.
 
   To run the libstdc++ test suite under the
   debug mode, use
diff --git a/libstdc++-v3/doc/xml/manual/test.xml 
b/libstdc++-v3/doc/xml/manual/test.xml
index 40926946fe7a..6b7f1b04a2ac 100644
--- a/libstdc++-v3/doc/xml/manual/test.xml
+++ b/libstdc++-v3/doc/xml/manual/test.xml
@@ -600,12 +600,13 @@ cat 27_io/objects/char/3_xin.in | a.out
   Since GCC 14, the libstdc++ testsuite has built-in support for running
   tests with more than one -std, similar to the G++ tests.
   Adding set v3_std_list { 11 17 23 } to
-  ~/.dejagnurc or a file named by the
+  ~/.dejagnurc or to a file named by the
   DEJAGNU environment variable will cause every test to
   be run three times, using a different -std each time.
   Alternatively, a list of standard versions to test with can be specified
   as a comma-separated list in the GLIBCXX_TESTSUITE_STDS
-  environment variable.
+  environment variable, e.g. GLIBCXX_TESTSUITE_STDS=11,17,23
+  is equivalent to the v3_std_list value above.
 
 
 


[gcc r15-4515] libstdc++: Fix order of [[...]] and __attribute__((...)) attrs [PR117220]

2024-10-21 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:cba80691251efccf44ab9aecb26558319605c9ea

commit r15-4515-gcba80691251efccf44ab9aecb26558319605c9ea
Author: Jonathan Wakely 
Date:   Mon Oct 21 12:09:36 2024 +0100

libstdc++: Fix order of [[...]] and __attribute__((...)) attrs [PR117220]

GCC allows these in either order, but Clang doesn't like the C++11-style
[[__nodiscard__]] coming after __attribute__((__always_inline__)).

libstdc++-v3/ChangeLog:

PR libstdc++/117220
* include/bits/stl_iterator.h: Move _GLIBCXX_NODISCARD
annotations after __attribute__((__always_inline__)).

Diff:
---
 libstdc++-v3/include/bits/stl_iterator.h | 46 
 1 file changed, 23 insertions(+), 23 deletions(-)

diff --git a/libstdc++-v3/include/bits/stl_iterator.h 
b/libstdc++-v3/include/bits/stl_iterator.h
index 26c5eab4b4e8..1fbc115b1163 100644
--- a/libstdc++-v3/include/bits/stl_iterator.h
+++ b/libstdc++-v3/include/bits/stl_iterator.h
@@ -1077,13 +1077,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   // Forward iterator requirements
 
-  __attribute__((__always_inline__)) _GLIBCXX_NODISCARD
+  _GLIBCXX_NODISCARD __attribute__((__always_inline__))
   _GLIBCXX_CONSTEXPR
   reference
   operator*() const _GLIBCXX_NOEXCEPT
   { return *_M_current; }
 
-  __attribute__((__always_inline__)) _GLIBCXX_NODISCARD
+  _GLIBCXX_NODISCARD __attribute__((__always_inline__))
   _GLIBCXX_CONSTEXPR
   pointer
   operator->() const _GLIBCXX_NOEXCEPT
@@ -1123,7 +1123,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   // Random access iterator requirements
 
-  __attribute__((__always_inline__)) _GLIBCXX_NODISCARD
+  _GLIBCXX_NODISCARD __attribute__((__always_inline__))
   _GLIBCXX_CONSTEXPR
   reference
   operator[](difference_type __n) const _GLIBCXX_NOEXCEPT
@@ -1135,7 +1135,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   operator+=(difference_type __n) _GLIBCXX_NOEXCEPT
   { _M_current += __n; return *this; }
 
-  __attribute__((__always_inline__)) _GLIBCXX_NODISCARD
+  _GLIBCXX_NODISCARD __attribute__((__always_inline__))
   _GLIBCXX_CONSTEXPR
   __normal_iterator
   operator+(difference_type __n) const _GLIBCXX_NOEXCEPT
@@ -1147,13 +1147,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   operator-=(difference_type __n) _GLIBCXX_NOEXCEPT
   { _M_current -= __n; return *this; }
 
-  __attribute__((__always_inline__)) _GLIBCXX_NODISCARD
+  _GLIBCXX_NODISCARD __attribute__((__always_inline__))
   _GLIBCXX_CONSTEXPR
   __normal_iterator
   operator-(difference_type __n) const _GLIBCXX_NOEXCEPT
   { return __normal_iterator(_M_current - __n); }
 
-  __attribute__((__always_inline__)) _GLIBCXX_NODISCARD
+  _GLIBCXX_NODISCARD __attribute__((__always_inline__))
   _GLIBCXX_CONSTEXPR
   const _Iterator&
   base() const _GLIBCXX_NOEXCEPT
@@ -1209,7 +1209,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #else
// Forward iterator requirements
   template
-__attribute__((__always_inline__)) _GLIBCXX_NODISCARD _GLIBCXX_CONSTEXPR
+_GLIBCXX_NODISCARD __attribute__((__always_inline__)) _GLIBCXX_CONSTEXPR
 inline bool
 operator==(const __normal_iterator<_IteratorL, _Container>& __lhs,
   const __normal_iterator<_IteratorR, _Container>& __rhs)
@@ -1217,7 +1217,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { return __lhs.base() == __rhs.base(); }
 
   template
-__attribute__((__always_inline__)) _GLIBCXX_NODISCARD _GLIBCXX_CONSTEXPR
+_GLIBCXX_NODISCARD __attribute__((__always_inline__)) _GLIBCXX_CONSTEXPR
 inline bool
 operator==(const __normal_iterator<_Iterator, _Container>& __lhs,
   const __normal_iterator<_Iterator, _Container>& __rhs)
@@ -1225,7 +1225,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { return __lhs.base() == __rhs.base(); }
 
   template
-__attribute__((__always_inline__)) _GLIBCXX_NODISCARD _GLIBCXX_CONSTEXPR
+_GLIBCXX_NODISCARD __attribute__((__always_inline__)) _GLIBCXX_CONSTEXPR
 inline bool
 operator!=(const __normal_iterator<_IteratorL, _Container>& __lhs,
   const __normal_iterator<_IteratorR, _Container>& __rhs)
@@ -1233,7 +1233,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { return __lhs.base() != __rhs.base(); }
 
   template
-__attribute__((__always_inline__)) _GLIBCXX_NODISCARD _GLIBCXX_CONSTEXPR
+_GLIBCXX_NODISCARD __attribute__((__always_inline__)) _GLIBCXX_CONSTEXPR
 inline bool
 operator!=(const __normal_iterator<_Iterator, _Container>& __lhs,
   const __normal_iterator<_Iterator, _Container>& __rhs)
@@ -1242,7 +1242,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   // Random access iterator requirements
   template
-__attribute__((__always_inline__)) _GLIBCXX_NODISCARD _GLIBCXX_CONSTEXPR
+_GLIBCXX_NODISCARD __attribute__((__always_inline__)) _GLIBCXX_CONSTEXPR
 inline bool
 operator<(const __normal_iterator<_IteratorL, _Container>& __

[gcc r15-4475] libstdc++: Inline memmove optimizations for std::copy etc. [PR115444]

2024-10-18 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:7ed561f63e7955df4d194669998176df5ef47803

commit r15-4475-g7ed561f63e7955df4d194669998176df5ef47803
Author: Jonathan Wakely 
Date:   Thu Jun 27 13:01:18 2024 +0100

libstdc++: Inline memmove optimizations for std::copy etc. [PR115444]

This removes all the __copy_move class template specializations that
decide how to optimize std::copy and std::copy_n. We can inline those
optimizations into the algorithms, using if-constexpr (and macros for
C++98 compatibility) and remove the code dispatching to the various
class template specializations.

Doing this means we implement the optimization directly for std::copy_n
instead of deferring to std::copy, That avoids the unwanted consequence
of advancing the iterator in copy_n only to take the difference later to
get back to the length that we already had in copy_n originally (as
described in PR 115444).

With the new flattened implementations, we can also lower contiguous
iterators to pointers in std::copy/std::copy_n/std::copy_backwards, so
that they benefit from the same memmove optimizations as pointers.
There's a subtlety though: contiguous iterators can potentially throw
exceptions to exit the algorithm early.  So we can only transform the
loop to memmove if dereferencing the iterator is noexcept. We don't
check that incrementing the iterator is noexcept because we advance the
contiguous iterators before using memmove, so that if incrementing would
throw, that happens first. I am writing a proposal (P3349R0) which would
make this unnecessary, so I hope we can drop the nothrow requirements
later.

This change also solves PR 114817 by checking is_trivially_assignable
before optimizing copy/copy_n etc. to memmove. It's not enough to check
that the types are trivially copyable (a precondition for using memmove
at all), we also need to check that the specific assignment that would
be performed by the algorithm is also trivial. Replacing a non-trivial
assignment with memmove would be observable, so not allowed.

libstdc++-v3/ChangeLog:

PR libstdc++/115444
PR libstdc++/114817
* include/bits/stl_algo.h (__copy_n): Remove generic overload
and overload for random access iterators.
(copy_n): Inline generic version of __copy_n here. Do not defer
to std::copy for random access iterators.
* include/bits/stl_algobase.h (__copy_move): Remove.
(__nothrow_contiguous_iterator, __memcpyable_iterators): New
concepts.
(__assign_one, _GLIBCXX_TO_ADDR, _GLIBCXX_ADVANCE): New helpers.
(__copy_move_a2): Inline __copy_move logic and conditional
memmove optimization into the most generic overload.
(__copy_n_a): Likewise.
(__copy_move_backward): Remove.
(__copy_move_backward_a2): Inline __copy_move_backward logic and
memmove optimization into the most generic overload.
* 
testsuite/20_util/specialized_algorithms/uninitialized_copy/114817.cc:
New test.
* 
testsuite/20_util/specialized_algorithms/uninitialized_copy_n/114817.cc:
New test.
* testsuite/25_algorithms/copy/114817.cc: New test.
* testsuite/25_algorithms/copy/115444.cc: New test.
* testsuite/25_algorithms/copy_n/114817.cc: New test.

Reviewed-by: Patrick Palka 

Diff:
---
 libstdc++-v3/include/bits/stl_algo.h   |  24 +-
 libstdc++-v3/include/bits/stl_algobase.h   | 412 +++--
 .../uninitialized_copy/114817.cc   |  39 ++
 .../uninitialized_copy_n/114817.cc |  39 ++
 .../testsuite/25_algorithms/copy/114817.cc |  38 ++
 .../testsuite/25_algorithms/copy/115444.cc |  93 +
 .../testsuite/25_algorithms/copy_n/114817.cc   |  38 ++
 7 files changed, 461 insertions(+), 222 deletions(-)

diff --git a/libstdc++-v3/include/bits/stl_algo.h 
b/libstdc++-v3/include/bits/stl_algo.h
index a1ef665506d1..489ce7e14d24 100644
--- a/libstdc++-v3/include/bits/stl_algo.h
+++ b/libstdc++-v3/include/bits/stl_algo.h
@@ -665,25 +665,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   return __result;
 }
 
-  template
-_GLIBCXX20_CONSTEXPR
-_OutputIterator
-__copy_n(_InputIterator __first, _Size __n,
-_OutputIterator __result, input_iterator_tag)
-{
-  return std::__niter_wrap(__result,
-  __copy_n_a(__first, __n,
- std::__niter_base(__result), true));
-}
-
-  template
-_GLIBCXX20_CONSTEXPR
-inline _OutputIterator
-__copy_n(_RandomAccessIterator __first, _Size __n,
-_OutputIterator __result, random_access_iterator_tag)
-{ return std::copy(__first, __first + __n, __result); }
-
   /**
*  @brief Copies th

[gcc r15-4478] libstdc++: Reuse std::__assign_one in

2024-10-18 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:d0a9ae1321f01c33b7ee377249cad30187061c0c

commit r15-4478-gd0a9ae1321f01c33b7ee377249cad30187061c0c
Author: Jonathan Wakely 
Date:   Mon Oct 14 23:34:20 2024 +0100

libstdc++: Reuse std::__assign_one in 

Use std::__assign_one instead of ranges::__assign_one. Adjust the uses,
because std::__assign_one has the arguments in the opposite order (the
same order as an assignment expression).

libstdc++-v3/ChangeLog:

* include/bits/ranges_algobase.h (ranges::__assign_one): Remove.
(__copy_or_move, __copy_or_move_backward): Use std::__assign_one
instead of ranges::__assign_one.

Reviewed-by: Patrick Palka 

Diff:
---
 libstdc++-v3/include/bits/ranges_algobase.h | 22 ++
 1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/libstdc++-v3/include/bits/ranges_algobase.h 
b/libstdc++-v3/include/bits/ranges_algobase.h
index 0345ea850a4e..df4e770e7a65 100644
--- a/libstdc++-v3/include/bits/ranges_algobase.h
+++ b/libstdc++-v3/include/bits/ranges_algobase.h
@@ -225,16 +225,6 @@ namespace ranges
  copy_backward_result<_Iter, _Out>>
 __copy_or_move_backward(_Iter __first, _Sent __last, _Out __result);
 
-  template
-constexpr void
-__assign_one(_Iter& __iter, _Out& __result)
-{
-  if constexpr (_IsMove)
- *__result = std::move(*__iter);
-  else
- *__result = *__iter;
-}
-
   template _Sent,
   weakly_incrementable _Out>
@@ -294,14 +284,14 @@ namespace ranges
__builtin_memmove(__result, __first,
  sizeof(_ValueTypeI) * __num);
  else if (__num == 1)
-   ranges::__assign_one<_IsMove>(__first, __result);
+   std::__assign_one<_IsMove>(__result, __first);
  return {__first + __num, __result + __num};
}
}
 
  for (auto __n = __last - __first; __n > 0; --__n)
{
- ranges::__assign_one<_IsMove>(__first, __result);
+ std::__assign_one<_IsMove>(__result, __first);
  ++__first;
  ++__result;
}
@@ -311,7 +301,7 @@ namespace ranges
{
  while (__first != __last)
{
- ranges::__assign_one<_IsMove>(__first, __result);
+ std::__assign_one<_IsMove>(__result, __first);
  ++__first;
  ++__result;
}
@@ -423,7 +413,7 @@ namespace ranges
__builtin_memmove(__result, __first,
  sizeof(_ValueTypeI) * __num);
  else if (__num == 1)
-   ranges::__assign_one<_IsMove>(__first, __result);
+   std::__assign_one<_IsMove>(__result, __first);
  return {__first + __num, __result};
}
}
@@ -435,7 +425,7 @@ namespace ranges
{
  --__tail;
  --__result;
- ranges::__assign_one<_IsMove>(__tail, __result);
+ std::__assign_one<_IsMove>(__result, __tail);
}
  return {std::move(__lasti), std::move(__result)};
}
@@ -448,7 +438,7 @@ namespace ranges
{
  --__tail;
  --__result;
- ranges::__assign_one<_IsMove>(__tail, __result);
+ std::__assign_one<_IsMove>(__result, __tail);
}
  return {std::move(__lasti), std::move(__result)};
}


[gcc r15-4476] libstdc++: Add nodiscard to std::find

2024-10-18 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:5546be4c24cd1085c8e43b5635be56a9b591c626

commit r15-4476-g5546be4c24cd1085c8e43b5635be56a9b591c626
Author: Jonathan Wakely 
Date:   Thu Oct 17 21:18:14 2024 +0100

libstdc++: Add nodiscard to std::find

I missed this one out in r14-9478-gdf483ebd24689a but I don't think that
was intentional. I see no reason std::find shouldn't be [[nodiscard]].

libstdc++-v3/ChangeLog:

* include/bits/stl_algo.h (find): Add nodiscard.

Reviewed-by: Patrick Palka 

Diff:
---
 libstdc++-v3/include/bits/stl_algo.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/bits/stl_algo.h 
b/libstdc++-v3/include/bits/stl_algo.h
index 489ce7e14d24..780bd8e5e826 100644
--- a/libstdc++-v3/include/bits/stl_algo.h
+++ b/libstdc++-v3/include/bits/stl_algo.h
@@ -3820,7 +3820,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
*  such that @c *i == @p __val, or @p __last if no such iterator exists.
   */
   template
-_GLIBCXX20_CONSTEXPR
+_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
 inline _InputIterator
 find(_InputIterator __first, _InputIterator __last, const _Tp& __val)
 {


[gcc r15-4473] libstdc++: Refactor std::uninitialized_{copy, fill, fill_n} algos [PR68350]

2024-10-18 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:3abe751ea86e3472fa2c97bf2014f9f93f569019

commit r15-4473-g3abe751ea86e3472fa2c97bf2014f9f93f569019
Author: Jonathan Wakely 
Date:   Wed Oct 9 12:55:54 2024 +0100

libstdc++: Refactor std::uninitialized_{copy,fill,fill_n} algos [PR68350]

This refactors the std::uninitialized_copy, std::uninitialized_fill and
std::uninitialized_fill_n algorithms to directly perform memcpy/memset
optimizations instead of dispatching to std::copy/std::fill/std::fill_n.

The reasons for this are:

- Use 'if constexpr' to simplify and optimize compilation throughput, so
  dispatching to specialized class templates is only needed for C++98
  mode.
- Use memcpy instead of memmove, because the conditions on
  non-overlapping ranges are stronger for std::uninitialized_copy than
  for std::copy. Using memcpy might be a minor optimization.
- No special case for creating a range of one element, which std::copy
  needs to deal with (see PR libstdc++/108846). The uninitialized algos
  create new objects, which reuses storage and is allowed to clobber
  tail padding.
- Relax the conditions for using memcpy/memset, because the C++20 rules
  on implicit-lifetime types mean that we can rely on memcpy to begin
  lifetimes of trivially copyable types.  We don't need to require
  trivially default constructible, so don't need to limit the
  optimization to trivial types. See PR 68350 for more details.
- Remove the dependency on std::copy and std::fill. This should mean
  that stl_uninitialized.h no longer needs to include all of
  stl_algobase.h.  This isn't quite true yet, because we still use
  std::fill in __uninitialized_default and still use std::fill_n in
  __uninitialized_default_n. That will be fixed later.

Several tests need changes to the diagnostics matched by dg-error
because we no longer use the __constructible() function that had a
static assert in. Now we just get straightforward errors for attempting
to use a deleted constructor.

Two tests needed more signficant changes to the actual expected results
of executing the tests, because they were checking for old behaviour
which was incorrect according to the standard.
20_util/specialized_algorithms/uninitialized_copy/64476.cc was expecting
std::copy to be used for a call to std::uninitialized_copy involving two
trivially copyable types. That was incorrect behaviour, because a
non-trivial constructor should have been used, but using std::copy used
trivial default initialization followed by assignment.
20_util/specialized_algorithms/uninitialized_fill_n/sizes.cc was testing
the behaviour with a non-integral Size passed to uninitialized_fill_n,
but I wrote the test looking at the requirements of uninitialized_copy_n
which are not the same as uninitialized_fill_n. The former uses --n and
tests n > 0, but the latter just tests n-- (which will never be false
for a floating-point value with a fractional part).

libstdc++-v3/ChangeLog:

PR libstdc++/68350
PR libstdc++/93059
* include/bits/stl_uninitialized.h (__check_constructible)
(_GLIBCXX_USE_ASSIGN_FOR_INIT): Remove.
[C++98] (__unwrappable_niter): New trait.
(__uninitialized_copy): Replace use of std::copy.
(uninitialized_copy): Fix Doxygen comments. Open-code memcpy
optimization for C++11 and later.
(__uninitialized_fill): Replace use of std::fill.
(uninitialized_fill): Fix Doxygen comments. Open-code memset
optimization for C++11 and later.
(__uninitialized_fill_n): Replace use of std::fill_n.
(uninitialized_fill_n): Fix Doxygen comments. Open-code memset
optimization for C++11 and later.
* 
testsuite/20_util/specialized_algorithms/uninitialized_copy/64476.cc:
Adjust expected behaviour to match what the standard specifies.
* 
testsuite/20_util/specialized_algorithms/uninitialized_fill_n/sizes.cc:
Likewise.
* testsuite/20_util/specialized_algorithms/uninitialized_copy/1.cc:
Adjust dg-error directives.
* 
testsuite/20_util/specialized_algorithms/uninitialized_copy/89164.cc:
Likewise.
* 
testsuite/20_util/specialized_algorithms/uninitialized_copy_n/89164.cc:
Likewise.
* 
testsuite/20_util/specialized_algorithms/uninitialized_fill/89164.cc:
Likewise.
* 
testsuite/20_util/specialized_algorithms/uninitialized_fill_n/89164.cc:
Likewise.
* testsuite/23_containers/vector/cons/89164.cc: Likewise.
* testsuite/23_containers/vector/cons/89164_c++17.cc: Likewise.

Reviewed-by: Patrick Palka 

Diff:
---
 libstdc++-v3/include/bits/stl_uninitialized.h  | 379 ++

[gcc r15-4472] libstdc++: Move std::__niter_base and std::__niter_wrap to stl_iterator.h

2024-10-18 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:2608fcfe5fcff260d62379d8f74efb9be8df70f4

commit r15-4472-g2608fcfe5fcff260d62379d8f74efb9be8df70f4
Author: Jonathan Wakely 
Date:   Wed Oct 9 12:55:54 2024 +0100

libstdc++: Move std::__niter_base and std::__niter_wrap to stl_iterator.h

Move the functions for unwrapping and rewrapping __normal_iterator
objects to the same file as the definition of __normal_iterator itself.

This will allow a later commit to make use of std::__niter_base in other
headers without having to include all of .

libstdc++-v3/ChangeLog:

* include/bits/stl_algobase.h (__niter_base, __niter_wrap): Move
to ...
* include/bits/stl_iterator.h: ... here.
(__niter_base, __miter_base): Move all overloads to the end of
the header.
* testsuite/24_iterators/normal_iterator/wrapping.cc: New test.

Reviewed-by: Patrick Palka 

Diff:
---
 libstdc++-v3/include/bits/stl_algobase.h   |  45 ---
 libstdc++-v3/include/bits/stl_iterator.h   | 138 +++--
 .../24_iterators/normal_iterator/wrapping.cc   |  29 +
 3 files changed, 132 insertions(+), 80 deletions(-)

diff --git a/libstdc++-v3/include/bits/stl_algobase.h 
b/libstdc++-v3/include/bits/stl_algobase.h
index 384e5fdcdc99..751b7ad119b0 100644
--- a/libstdc++-v3/include/bits/stl_algobase.h
+++ b/libstdc++-v3/include/bits/stl_algobase.h
@@ -308,51 +308,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   return __a;
 }
 
-  // Fallback implementation of the function in bits/stl_iterator.h used to
-  // remove the __normal_iterator wrapper. See copy, fill, ...
-  template
-_GLIBCXX20_CONSTEXPR
-inline _Iterator
-__niter_base(_Iterator __it)
-_GLIBCXX_NOEXCEPT_IF(std::is_nothrow_copy_constructible<_Iterator>::value)
-{ return __it; }
-
-#if __cplusplus < 201103L
-  template
-_Ite
-__niter_base(const ::__gnu_debug::_Safe_iterator<_Ite, _Seq,
-std::random_access_iterator_tag>&);
-
- template
-_Ite
-__niter_base(const ::__gnu_debug::_Safe_iterator<
-::__gnu_cxx::__normal_iterator<_Ite, _Cont>, _Seq,
-std::random_access_iterator_tag>&);
-#else
-  template
-_GLIBCXX20_CONSTEXPR
-decltype(std::__niter_base(std::declval<_Ite>()))
-__niter_base(const ::__gnu_debug::_Safe_iterator<_Ite, _Seq,
-std::random_access_iterator_tag>&)
-noexcept(std::is_nothrow_copy_constructible<_Ite>::value);
-#endif
-
-  // Reverse the __niter_base transformation to get a
-  // __normal_iterator back again (this assumes that __normal_iterator
-  // is only used to wrap random access iterators, like pointers).
-  template
-_GLIBCXX20_CONSTEXPR
-inline _From
-__niter_wrap(_From __from, _To __res)
-{ return __from + (std::__niter_base(__res) - std::__niter_base(__from)); }
-
-  // No need to wrap, iterator already has the right type.
-  template
-_GLIBCXX20_CONSTEXPR
-inline _Iterator
-__niter_wrap(const _Iterator&, _Iterator __res)
-{ return __res; }
-
   // All of these auxiliary structs serve two purposes.  (1) Replace
   // calls to copy with memmove whenever possible.  (Memmove, not memcpy,
   // because the input and output ranges are permitted to overlap.)
diff --git a/libstdc++-v3/include/bits/stl_iterator.h 
b/libstdc++-v3/include/bits/stl_iterator.h
index 28a600c81cb2..be3fa6f7a349 100644
--- a/libstdc++-v3/include/bits/stl_iterator.h
+++ b/libstdc++-v3/include/bits/stl_iterator.h
@@ -654,24 +654,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #  endif // C++20
 # endif // __glibcxx_make_reverse_iterator
 
-  template
-_GLIBCXX20_CONSTEXPR
-auto
-__niter_base(reverse_iterator<_Iterator> __it)
--> decltype(__make_reverse_iterator(__niter_base(__it.base(
-{ return __make_reverse_iterator(__niter_base(__it.base())); }
-
   template
 struct __is_move_iterator >
   : __is_move_iterator<_Iterator>
 { };
-
-  template
-_GLIBCXX20_CONSTEXPR
-auto
-__miter_base(reverse_iterator<_Iterator> __it)
--> decltype(__make_reverse_iterator(__miter_base(__it.base(
-{ return __make_reverse_iterator(__miter_base(__it.base())); }
 #endif // C++11
 
   // 24.4.2.2.1 back_insert_iterator
@@ -1336,19 +1322,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { return __normal_iterator<_Iterator, _Container>(__i.base() + __n); }
 
 _GLIBCXX_END_NAMESPACE_VERSION
-} // namespace
+} // namespace __gnu_cxx
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-  template
-_GLIBCXX20_CONSTEXPR
-_Iterator
-__niter_base(__gnu_cxx::__normal_iterator<_Iterator, _Container> __it)
-_GLIBCXX_NOEXCEPT_IF(std::is_nothrow_copy_constructible<_Iterator>::value)
-{ return __it.base(); }
-
 #if __cplusplus >= 201103L && __cplusplus <= 201703L
   // Need to overload __to_address because the pointer_traits primary template
   // will deduce element_type

[gcc r13-9125] libstdc++: Make debug sequence members mutable [PR116369]

2024-10-17 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:aa0bee77b6d3f82b8c76703515767e79adac2738

commit r13-9125-gaa0bee77b6d3f82b8c76703515767e79adac2738
Author: Jonathan Wakely 
Date:   Wed Aug 21 12:29:32 2024 +0100

libstdc++: Make debug sequence members mutable [PR116369]

We need to be able to attach debug mode iterators to const containers,
so the safe iterator constructor uses const_cast to get a modifiable
pointer to the container. If the container was defined as const, that
const_cast to access its members results in undefined behaviour.  PR
116369 shows a case where it results in a segfault because the container
is in a rodata section (which shouldn't have happened, but the undefined
behaviour in the library still exists in any case).

This makes the _M_iterators and _M_const_iterators data members mutable,
so that it's safe to modify them even if the declared type of the
container is a const type.

Ideally we would not need the const_cast at all. Instead, the _M_attach
member (and everything it calls) should be const-qualified. That would
work fine now, because the members that it ends up modifying are
mutable. Making that change would require a number of new exports from
the shared library, and would require retaining the old non-const member
functions (maybe as symbol aliases) for backwards compatibility. That
might be worth changing at some point, but isn't done here.

libstdc++-v3/ChangeLog:

PR c++/116369
* include/debug/safe_base.h (_Safe_sequence_base::_M_iterators):
Add mutable specifier.
(_Safe_sequence_base::_M_const_iterators): Likewise.

(cherry picked from commit a35dd276cbf6236e08bcf6e56e62c2be41cf6e3c)

Diff:
---
 libstdc++-v3/include/debug/safe_base.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/debug/safe_base.h 
b/libstdc++-v3/include/debug/safe_base.h
index 1dfa9f68b65b..7169bb8ff376 100644
--- a/libstdc++-v3/include/debug/safe_base.h
+++ b/libstdc++-v3/include/debug/safe_base.h
@@ -191,10 +191,10 @@ namespace __gnu_debug
 
   public:
 /// The list of mutable iterators that reference this container
-_Safe_iterator_base* _M_iterators;
+mutable _Safe_iterator_base* _M_iterators;
 
 /// The list of constant iterators that reference this container
-_Safe_iterator_base* _M_const_iterators;
+mutable _Safe_iterator_base* _M_const_iterators;
 
 /// The container version number. This number may never be 0.
 mutable unsigned int _M_version;


[gcc r13-9135] libstdc++: Populate std::time_get::get's %c format for C locale

2024-10-17 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:39236ff82627398dec4b30964f540d0a223be200

commit r13-9135-g39236ff82627398dec4b30964f540d0a223be200
Author: Jonathan Wakely 
Date:   Tue Sep 24 23:20:56 2024 +0100

libstdc++: Populate std::time_get::get's %c format for C locale

We were using the empty string "" for D_T_FMT and ERA_D_T_FMT in the C
locale, instead of "%a %b %e %T %Y" as the C standard requires. Set it
correctly for each locale implementation that defines time_members.cc.

We can also explicitly set the _M_era_xxx pointers to the same values as
the corresponding _M_xxx ones, rather than setting them to point to
identical string literals. This doesn't rely on the compiler merging
string literals, and makes it more explicit that they're the same in the
C locale.

libstdc++-v3/ChangeLog:

* config/locale/dragonfly/time_members.cc
(__timepunct::_M_initialize_timepunc)
(__timepunct::_M_initialize_timepunc): Set
_M_date_time_format for C locale. Set %Ex formats to the same
values as the %x formats.
* config/locale/generic/time_members.cc: Likewise.
* config/locale/gnu/time_members.cc: Likewise.
* testsuite/22_locale/time_get/get/char/5.cc: New test.
* testsuite/22_locale/time_get/get/wchar_t/5.cc: New test.

(cherry picked from commit c534e37faccf481afa9bc28f0605ca0ec3846c89)

Diff:
---
 .../config/locale/dragonfly/time_members.cc| 16 +-
 libstdc++-v3/config/locale/generic/time_members.cc |  8 ++---
 libstdc++-v3/config/locale/gnu/time_members.cc | 16 +-
 .../testsuite/22_locale/time_get/get/char/5.cc | 37 ++
 .../testsuite/22_locale/time_get/get/wchar_t/5.cc  | 37 ++
 5 files changed, 94 insertions(+), 20 deletions(-)

diff --git a/libstdc++-v3/config/locale/dragonfly/time_members.cc 
b/libstdc++-v3/config/locale/dragonfly/time_members.cc
index 1dc83a6af6f3..88a0341d55ff 100644
--- a/libstdc++-v3/config/locale/dragonfly/time_members.cc
+++ b/libstdc++-v3/config/locale/dragonfly/time_members.cc
@@ -67,11 +67,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  _M_c_locale_timepunct = _S_get_c_locale();
 
  _M_data->_M_date_format = "%m/%d/%y";
- _M_data->_M_date_era_format = "%m/%d/%y";
+ _M_data->_M_date_era_format = _M_data->_M_date_format;
  _M_data->_M_time_format = "%H:%M:%S";
- _M_data->_M_time_era_format = "%H:%M:%S";
- _M_data->_M_date_time_format = "";
- _M_data->_M_date_time_era_format = "";
+ _M_data->_M_time_era_format = _M_data->_M_time_format;
+ _M_data->_M_date_time_format = "%a %b %e %T %Y";
+ _M_data->_M_date_time_era_format = _M_data->_M_date_time_format;
  _M_data->_M_am = "AM";
  _M_data->_M_pm = "PM";
  _M_data->_M_am_pm_format = "%I:%M:%S %p";
@@ -224,11 +224,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  _M_c_locale_timepunct = _S_get_c_locale();
 
  _M_data->_M_date_format = L"%m/%d/%y";
- _M_data->_M_date_era_format = L"%m/%d/%y";
+ _M_data->_M_date_era_format = _M_data->_M_date_format;
  _M_data->_M_time_format = L"%H:%M:%S";
- _M_data->_M_time_era_format = L"%H:%M:%S";
- _M_data->_M_date_time_format = L"";
- _M_data->_M_date_time_era_format = L"";
+ _M_data->_M_time_era_format = _M_data->_M_time_format;
+ _M_data->_M_date_time_format = L"%a %b %e %T %Y";
+ _M_data->_M_date_time_era_format = _M_data->_M_date_time_format;
  _M_data->_M_am = L"AM";
  _M_data->_M_pm = L"PM";
  _M_data->_M_am_pm_format = L"%I:%M:%S %p";
diff --git a/libstdc++-v3/config/locale/generic/time_members.cc 
b/libstdc++-v3/config/locale/generic/time_members.cc
index 369e1de4a972..03a4ecbc31a3 100644
--- a/libstdc++-v3/config/locale/generic/time_members.cc
+++ b/libstdc++-v3/config/locale/generic/time_members.cc
@@ -65,11 +65,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_data = new __timepunct_cache;
 
   _M_data->_M_date_format = "%m/%d/%y";
-  _M_data->_M_date_era_format = "%m/%d/%y";
+  _M_data->_M_date_era_format = _M_data->_M_date_format;
   _M_data->_M_time_format = "%H:%M:%S";
-  _M_data->_M_time_era_format = "%H:%M:%S";
-  _M_data->_M_date_time_format = "";
-  _M_data->_M_date_time_era_format = "";
+  _M_data->_M_time_era_format = _M_data->_M_time_format;
+  _M_data->_M_date_time_format = "%a %b %e %T %Y";
+  _M_data->_M_date_time_era_format = _M_data->_M_date_time_format;
   _M_data->_M_am = "AM";
   _M_data->_M_pm = "PM";
   _M_data->_M_am_pm_format = "%I:%M:%S %p";
diff --git a/libstdc++-v3/config/locale/gnu/time_members.cc 
b/libstdc++-v3/config/locale/gnu/time_members.cc
index 2d1ebdb33c0f..404451bedf6d 100644
--- a/libstdc++-v3/config/locale/gnu/time_members.cc
+++ b/libstdc++-v3/config/locale/gnu/time_members.cc
@@ -

[gcc r13-9132] libstdc++: Fix overwriting files with fs::copy_file on Windows

2024-10-17 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:8b3e47b4099f319e38d357f7c646f51040a13d6e

commit r13-9132-g8b3e47b4099f319e38d357f7c646f51040a13d6e
Author: Jonathan Wakely 
Date:   Tue Jul 30 10:55:55 2024 +0100

libstdc++: Fix overwriting files with fs::copy_file on Windows

There are no inode numbers on Windows filesystems, so stat_type::st_ino
is always zero and the check for equivalent files in do_copy_file was
incorrectly identifying distinct files as equivalent. This caused
copy_file to incorrectly report errors when trying to overwrite existing
files.

The fs::equivalent function already does the right thing on Windows, so
factor that logic out into a new function that can be reused by
fs::copy_file.

The tests for fs::copy_file were quite inadequate, so this also adds
checks for that function's error conditions.

libstdc++-v3/ChangeLog:

* src/c++17/fs_ops.cc (auto_win_file_handle): Change constructor
parameter from const path& to const wchar_t*.
(fs::equiv_files): New function.
(fs::equivalent): Use equiv_files.
* src/filesystem/ops-common.h (fs::equiv_files): Declare.
(do_copy_file): Use equiv_files.
* src/filesystem/ops.cc (fs::equiv_files): Define.
(fs::copy, fs::equivalent): Use equiv_files.
* testsuite/27_io/filesystem/operations/copy.cc: Test
overwriting directory contents recursively.
* testsuite/27_io/filesystem/operations/copy_file.cc: Test
overwriting existing files.

(cherry picked from commit 017e3f89b081e4828a588a3bd27b5feacea042b7)

Diff:
---
 libstdc++-v3/src/c++17/fs_ops.cc   |  71 +++-
 libstdc++-v3/src/filesystem/ops-common.h   |  10 +-
 libstdc++-v3/src/filesystem/ops.cc |  18 ++-
 .../testsuite/27_io/filesystem/operations/copy.cc  |   9 ++
 .../27_io/filesystem/operations/copy_file.cc   | 122 +
 5 files changed, 197 insertions(+), 33 deletions(-)

diff --git a/libstdc++-v3/src/c++17/fs_ops.cc b/libstdc++-v3/src/c++17/fs_ops.cc
index 20e6cfc95d03..26b029821822 100644
--- a/libstdc++-v3/src/c++17/fs_ops.cc
+++ b/libstdc++-v3/src/c++17/fs_ops.cc
@@ -351,7 +351,7 @@ fs::copy(const path& from, const path& to, copy_options 
options,
   f = make_file_status(from_st);
 
   if (exists(t) && !is_other(t) && !is_other(f)
-  && to_st.st_dev == from_st.st_dev && to_st.st_ino == from_st.st_ino)
+  && fs::equiv_files(from.c_str(), from_st, to.c_str(), to_st, ec))
 {
   ec = std::make_error_code(std::errc::file_exists);
   return;
@@ -830,8 +830,8 @@ namespace
   struct auto_win_file_handle
   {
 explicit
-auto_win_file_handle(const fs::path& p_)
-: handle(CreateFileW(p_.c_str(), 0,
+auto_win_file_handle(const wchar_t* p)
+: handle(CreateFileW(p, 0,
 FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0))
 { }
@@ -851,6 +851,44 @@ namespace
 }
 #endif
 
+#ifdef _GLIBCXX_HAVE_SYS_STAT_H
+#ifdef NEED_DO_COPY_FILE // Only define this once, not in cow-fs_ops.o too
+bool
+fs::equiv_files([[maybe_unused]] const char_type* p1, const stat_type& st1,
+   [[maybe_unused]] const char_type* p2, const stat_type& st2,
+   [[maybe_unused]] error_code& ec)
+{
+#if ! _GLIBCXX_FILESYSTEM_IS_WINDOWS
+  // For POSIX the device ID and inode number uniquely identify a file.
+  return st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino;
+#else
+  // For Windows st_ino is not set, so can't be used to distinguish files.
+  // We can compare modes and device IDs as a cheap initial check:
+  if (st1.st_mode != st2.st_mode || st1.st_dev != st2.st_dev)
+return false;
+
+  // Need to use GetFileInformationByHandle to get more info about the files.
+  auto_win_file_handle h1(p1);
+  auto_win_file_handle h2(p2);
+  if (!h1 || !h2)
+{
+  if (!h1 && !h2)
+   ec = __last_system_error();
+  return false;
+}
+  if (!h1.get_info() || !h2.get_info())
+{
+  ec = __last_system_error();
+  return false;
+}
+  return h1.info.dwVolumeSerialNumber == h2.info.dwVolumeSerialNumber
+  && h1.info.nFileIndexHigh == h2.info.nFileIndexHigh
+  && h1.info.nFileIndexLow == h2.info.nFileIndexLow;
+#endif // _GLIBCXX_FILESYSTEM_IS_WINDOWS
+}
+#endif // NEED_DO_COPY_FILE
+#endif // _GLIBCXX_HAVE_SYS_STAT_H
+
 bool
 fs::equivalent(const path& p1, const path& p2, error_code& ec) noexcept
 {
@@ -882,30 +920,7 @@ fs::equivalent(const path& p1, const path& p2, error_code& 
ec) noexcept
   ec.clear();
   if (is_other(s1) || is_other(s2))
return false;
-#if _GLIBCXX_FILESYSTEM_IS_WINDOWS
-  // st_ino is not set, so can't be used to distinguish files
-  if (st1.st_mode != st2.st_mode || st1.st_dev != st2.st_dev)
-   return false;
-
-  auto_win_fi

[gcc r13-9134] libstdc++: Document missing features for old std::string ABI [PR116777]

2024-10-17 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:68e267ea80ec5ad3044959f1eae51254579b34c8

commit r13-9134-g68e267ea80ec5ad3044959f1eae51254579b34c8
Author: Jonathan Wakely 
Date:   Fri Sep 20 17:35:48 2024 +0100

libstdc++: Document missing features for old std::string ABI [PR116777]

There are several features that are not supported when using the old
std::string ABI. It's possible that PR 81967 will get fixed, but the
missing C++20 features almost certainly won't be. Document this in the
manual.

libstdc++-v3/ChangeLog:

PR libstdc++/116777
* doc/xml/manual/using.xml: Document features that are not
supported for the gcc4-compatible ABI.
* doc/html/manual/using_dual_abi.html: Regenerate.

(cherry picked from commit 82309222300acf68e345b32155df21e1b876144e)

Diff:
---
 libstdc++-v3/doc/html/manual/using_dual_abi.html | 18 +++-
 libstdc++-v3/doc/xml/manual/using.xml| 26 +++-
 2 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/doc/html/manual/using_dual_abi.html 
b/libstdc++-v3/doc/html/manual/using_dual_abi.html
index 916ac575f64b..939eedae3629 100644
--- a/libstdc++-v3/doc/html/manual/using_dual_abi.html
+++ b/libstdc++-v3/doc/html/manual/using_dual_abi.html
@@ -22,7 +22,7 @@
   of the macro is 1 which causes the new ABI to 
be active,
   so to use the old ABI you must explicitly define the macro to
   0 before including any library headers.
-  (Be aware that some GNU/Linux distributions configure GCC 5 differently so
+  (Be aware that some GNU/Linux distributions configured GCC 5 differently so
   that the default value of the macro is 0 and 
users must
   define it to 1 to enable the new ABI.)
  Although the changes were made for C++11 conformance, the choice of ABI
@@ -72,6 +72,22 @@
   Handlers for std::exception will always catch
   iostreams exceptions, because the old and new type both inherit from
   std::exception.
+
+  Some features are not supported when using the old ABI, including:
+  
+Using std::string::const_iterator for
+positional arguments to member functions such as
+std::string::erase.
+  
+Allocator propagation in std::string.
+  
+Using std::string at compile-time in
+constexpr functions.
+  
+Class std::chrono::time_zone and all 
related APIs.
+  
+The  header.
+  
 Troubleshooting
 If you get linker errors about undefined references to symbols
   that involve types in the std::__cxx11 namespace 
or the tag
   [abi:cxx11] then it probably indicates that you 
are trying to
diff --git a/libstdc++-v3/doc/xml/manual/using.xml 
b/libstdc++-v3/doc/xml/manual/using.xml
index 42890f3b1801..3710465e5c1d 100644
--- a/libstdc++-v3/doc/xml/manual/using.xml
+++ b/libstdc++-v3/doc/xml/manual/using.xml
@@ -1223,7 +1223,7 @@ g++ -Winvalid-pch -I. -include stdc++.h -H -g -O2 
hello.cc -o test.exe
   of the macro is 1 which causes the new ABI to be active,
   so to use the old ABI you must explicitly define the macro to
   0 before including any library headers.
-  (Be aware that some GNU/Linux distributions configure GCC 5 differently so
+  (Be aware that some GNU/Linux distributions configured GCC 5 differently so
   that the default value of the macro is 0 and users must
   define it to 1 to enable the new ABI.)
 
@@ -1283,6 +1283,30 @@ g++ -Winvalid-pch -I. -include stdc++.h -H -g -O2 
hello.cc -o test.exe
   std::exception.
 
 
+
+  Some features are not supported when using the old ABI, including:
+  
+  
+Using std::string::const_iterator for
+positional arguments to member functions such as
+std::string::erase.
+  
+  
+Allocator propagation in std::string.
+  
+  
+Using std::string at compile-time in
+constexpr functions.
+  
+  
+Class std::chrono::time_zone and all related APIs.
+  
+  
+The  header.
+  
+  
+
+
 Troubleshooting
 
  If you get linker errors about undefined references to symbols


[gcc r13-9129] libstdc++: Make std::basic_format_context non-copyable [PR114387]

2024-10-17 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:bdf15cc4ac451e75a7e2b037fcf39cf8ac8f4a6b

commit r13-9129-gbdf15cc4ac451e75a7e2b037fcf39cf8ac8f4a6b
Author: Jonathan Wakely 
Date:   Wed Jul 10 10:27:24 2024 +0100

libstdc++: Make std::basic_format_context non-copyable [PR114387]

Users are not supposed to create objects of this type, and there's no
reason it needs to be copyable. LWG 4061 makes it non-copyable and
non-default constructible.

libstdc++-v3/ChangeLog:

PR libstdc++/114387
* include/std/format (basic_format_context): Define copy
operations as deleted, as per LWG 4061.
* testsuite/std/format/context.cc: New test.

(cherry picked from commit d8cd8521185436ea45ed48c5dd481277e9b8a98d)

Diff:
---
 libstdc++-v3/include/std/format  |  7 +-
 libstdc++-v3/testsuite/std/format/context.cc | 36 
 2 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index d69703a283ea..e00cfbe65c53 100644
--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -3461,6 +3461,12 @@ namespace __format
   : _M_args(__args), _M_out(std::move(__out)), _M_loc(__loc)
   { }
 
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // 4061. Should std::basic_format_context be
+  //   default-constructible/copyable/movable?
+  basic_format_context(const basic_format_context&) = delete;
+  basic_format_context& operator=(const basic_format_context&) = delete;
+
   template
friend _Out2
__format::__do_vformat_to(_Out2, basic_string_view<_CharT2>,
@@ -3468,7 +3474,6 @@ namespace __format
  const locale*);
 
 public:
-  basic_format_context() = default;
   ~basic_format_context() = default;
 
   using iterator = _Out;
diff --git a/libstdc++-v3/testsuite/std/format/context.cc 
b/libstdc++-v3/testsuite/std/format/context.cc
new file mode 100644
index ..5cc5e9c9ba22
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/format/context.cc
@@ -0,0 +1,36 @@
+// { dg-do compile { target c++20 } }
+
+#include 
+
+template
+concept format_context_reqs = std::is_destructible_v
+  && (!std::is_default_constructible_v)
+  && (!std::is_copy_constructible_v)
+  && (!std::is_move_constructible_v)
+  && (!std::is_copy_assignable_v)
+  && (!std::is_move_assignable_v)
+  && requires (Context& ctx, const Context& cctx) {
+typename Context::iterator;
+typename Context::char_type;
+requires std::same_as,
+ std::formatter>;
+{ ctx.locale() } -> std::same_as;
+{ ctx.out() } -> std::same_as;
+{ ctx.advance_to(ctx.out()) } -> std::same_as;
+{ cctx.arg(1) } -> std::same_as>;
+  };
+
+template
+constexpr bool
+check(std::basic_format_context*)
+{
+  using context = std::basic_format_context;
+  static_assert( format_context_reqs );
+  static_assert( std::is_same_v );
+  static_assert( std::is_same_v );
+  return true;
+}
+
+static_assert( check( (std::format_context*)nullptr) );
+static_assert( check( (std::wformat_context*)nullptr) );
+static_assert( check( (std::basic_format_context*)nullptr) );


[gcc r13-9127] libstdc++: Specialize std::disable_sized_sentinel_for for std::move_iterator [PR116549]

2024-10-17 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:a71a9d25db19dddcb07972af3b568708b6dcbca1

commit r13-9127-ga71a9d25db19dddcb07972af3b568708b6dcbca1
Author: Jonathan Wakely 
Date:   Mon Sep 2 11:29:13 2024 +0100

libstdc++: Specialize std::disable_sized_sentinel_for for 
std::move_iterator [PR116549]

LWG 3736 added a partial specialization of this variable template for
two std::move_iterator types. This is needed for the case where the
types satisfy std::sentinel_for and are subtractable, but do not model
the semantics requirements of std::sized_sentinel_for.

libstdc++-v3/ChangeLog:

PR libstdc++/116549
* include/bits/stl_iterator.h (disable_sized_sentinel_for):
Define specialization for two move_iterator types, as per LWG
3736.
* testsuite/24_iterators/move_iterator/lwg3736.cc: New test.

(cherry picked from commit 819deae0a5bee079a7d5582fafaa098c26144ae8)

Diff:
---
 libstdc++-v3/include/bits/stl_iterator.h   |  8 
 .../24_iterators/move_iterator/lwg3736.cc  | 52 ++
 2 files changed, 60 insertions(+)

diff --git a/libstdc++-v3/include/bits/stl_iterator.h 
b/libstdc++-v3/include/bits/stl_iterator.h
index b13f4f8ddbfb..203ccc7bf6b4 100644
--- a/libstdc++-v3/include/bits/stl_iterator.h
+++ b/libstdc++-v3/include/bits/stl_iterator.h
@@ -1833,6 +1833,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { return _ReturnType(__i); }
 
 #if __cplusplus > 201703L && __cpp_lib_concepts
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // 3736.  move_iterator missing disable_sized_sentinel_for specialization
+  template
+requires (!sized_sentinel_for<_Iterator1, _Iterator2>)
+inline constexpr bool
+disable_sized_sentinel_for,
+  move_iterator<_Iterator2>> = true;
+
   // [iterators.common] Common iterators
 
   namespace __detail
diff --git a/libstdc++-v3/testsuite/24_iterators/move_iterator/lwg3736.cc 
b/libstdc++-v3/testsuite/24_iterators/move_iterator/lwg3736.cc
new file mode 100644
index ..eaf791b30893
--- /dev/null
+++ b/libstdc++-v3/testsuite/24_iterators/move_iterator/lwg3736.cc
@@ -0,0 +1,52 @@
+// { dg-do compile { target c++20 } }
+
+// 3736.  move_iterator missing disable_sized_sentinel_for specialization
+
+#include 
+
+template using MoveIter = std::move_iterator;
+
+using std::sized_sentinel_for;
+using std::disable_sized_sentinel_for;
+
+// These assertions always passed, even without LWG 3736:
+static_assert(sized_sentinel_for, MoveIter>);
+static_assert(sized_sentinel_for, MoveIter>);
+static_assert(not sized_sentinel_for, MoveIter>);
+static_assert(not sized_sentinel_for, std::default_sentinel_t>);
+static_assert(not disable_sized_sentinel_for, MoveIter>);
+
+// These types don't satisfy sized_sentinel_for anyway (because the subtraction
+// is ill-formed) but LWG 3736 makes the variable template explicitly false:
+static_assert(disable_sized_sentinel_for, MoveIter>);
+
+struct Iter
+{
+  using iterator_category = std::random_access_iterator_tag;
+  using value_type = int;
+  using pointer = int*;
+  using reference = int&;
+  using difference_type = long;
+
+  Iter() = default;
+  Iter& operator++();
+  Iter operator++(int);
+  Iter& operator--();
+  Iter operator--(int);
+  reference operator*() const;
+  pointer operator->() const;
+  Iter& operator+=(difference_type);
+  Iter& operator-=(difference_type);
+  friend Iter operator+(Iter, difference_type);
+  friend Iter operator+(difference_type, Iter);
+  friend Iter operator-(Iter, difference_type);
+  friend difference_type operator-(Iter, Iter);
+  bool operator==(Iter) const;
+};
+
+// Specialize the variable template so that Iter is not its own sized sentinel:
+template<> constexpr bool std::disable_sized_sentinel_for = true;
+static_assert( not sized_sentinel_for );
+
+// LWG 3736 means that affects std::move_iterator as well:
+static_assert( not sized_sentinel_for, MoveIter> );


[gcc r13-9126] libstdc++: Fix Python deprecation warning in printers.py

2024-10-17 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:bf88c9a1549f4f1e8ee096da354d2fdfc7808bfb

commit r13-9126-gbf88c9a1549f4f1e8ee096da354d2fdfc7808bfb
Author: Jonathan Wakely 
Date:   Wed Oct 16 09:22:37 2024 +0100

libstdc++: Fix Python deprecation warning in printers.py

python/libstdcxx/v6/printers.py:1355: DeprecationWarning: 'count' is passed 
as positional argument

The Python docs say:

  Deprecated since version 3.13: Passing count and flags as positional
  arguments is deprecated. In future Python versions they will be
  keyword-only parameters.

Using a keyword argument for count only became possible with Python 3.1
so introduce a new function to do the substitution.

libstdc++-v3/ChangeLog:

* python/libstdcxx/v6/printers.py (strip_fundts_namespace): New.
(StdExpAnyPrinter, StdExpOptionalPrinter): Use it.

(cherry picked from commit b9e98bb9919fa9f07782f23f79b3d35abb9ff542)

Diff:
---
 libstdc++-v3/python/libstdcxx/v6/printers.py | 19 +--
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py 
b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 7e16a49aeb0b..24b8c1ae5083 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -220,6 +220,16 @@ def strip_versioned_namespace(typename):
 return typename.replace(_versioned_namespace, '')
 
 
+def strip_fundts_namespace(typ):
+"""Remove "fundamentals_vN" inline namespace from qualified type name."""
+pattern = r'^std::experimental::fundamentals_v\d::'
+repl = 'std::experimental::'
+if sys.version_info[0] == 2:
+return re.sub(pattern, repl, typ, 1)
+else: # Technically this needs Python 3.1 but nobody should be using 3.0
+return re.sub(pattern, repl, typ, count=1)
+
+
 def strip_inline_namespaces(type_str):
 """Remove known inline namespaces from the canonical name of a type."""
 type_str = strip_versioned_namespace(type_str)
@@ -1352,8 +1362,7 @@ class StdExpAnyPrinter(SingleObjContainerPrinter):
 
 def __init__(self, typename, val):
 self._typename = strip_versioned_namespace(typename)
-self._typename = re.sub(r'^std::experimental::fundamentals_v\d::',
-'std::experimental::', self._typename, 1)
+self._typename = strip_fundts_namespace(self._typename)
 self._val = val
 self._contained_type = None
 contained_value = None
@@ -1446,10 +1455,8 @@ class StdExpOptionalPrinter(SingleObjContainerPrinter):
 """Print a std::optional or std::experimental::optional."""
 
 def __init__(self, typename, val):
-typename = strip_versioned_namespace(typename)
-self._typename = re.sub(
-r'^std::(experimental::|)(fundamentals_v\d::|)(.*)',
-r'std::\1\3', typename, 1)
+self._typename = strip_versioned_namespace(typename)
+self._typename = strip_fundts_namespace(self._typename)
 payload = val['_M_payload']
 if self._typename.startswith('std::experimental'):
 engaged = val['_M_engaged']


[gcc r13-9130] libstdc++: Remove std::basic_format_args default constructor (LWG 4106)

2024-10-17 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:e085eeb59c9a77948492c7197d6eda6ec215361e

commit r13-9130-ge085eeb59c9a77948492c7197d6eda6ec215361e
Author: Jonathan Wakely 
Date:   Thu Jul 25 13:52:12 2024 +0100

libstdc++: Remove std::basic_format_args default constructor (LWG 4106)

There's no valid use case for default constructing this type, so the
committee approved removing the default constructor.

libstdc++-v3/ChangeLog:

* include/std/format (basic_format_args): Remove default
constructor, as per LWG 4106.
* testsuite/std/format/arguments/args.cc: Check it isn't default
constructible.

(cherry picked from commit 5be55447e256302324f38f04316a437909ae5847)

Diff:
---
 libstdc++-v3/include/std/format | 2 --
 libstdc++-v3/testsuite/std/format/arguments/args.cc | 4 
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index e00cfbe65c53..ed5bcf01504f 100644
--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -3292,8 +3292,6 @@ namespace __format
{ return {_Format_arg::template _S_to_enum<_Args>()...}; }
 
 public:
-  basic_format_args() noexcept = default;
-
   template
basic_format_args(const _Store<_Args...>& __store) noexcept;
 
diff --git a/libstdc++-v3/testsuite/std/format/arguments/args.cc 
b/libstdc++-v3/testsuite/std/format/arguments/args.cc
index e2e7a3e7ee54..cefd0b944717 100644
--- a/libstdc++-v3/testsuite/std/format/arguments/args.cc
+++ b/libstdc++-v3/testsuite/std/format/arguments/args.cc
@@ -4,6 +4,10 @@
 #include 
 #include 
 
+// LWG 4106. basic_format_args should not be default-constructible
+static_assert( ! std::is_default_constructible_v );
+static_assert( ! std::is_default_constructible_v );
+
 template
 bool equals(std::basic_format_arg fmt_arg, T expected) {
   return std::visit_format_arg([=](auto arg_val) {


[gcc r13-9128] libstdc++: Use direct-initialization for std::vector's allocator [PR115854]

2024-10-17 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:d166c3ecf633a939777d02bc5c9ad4e2449e6d98

commit r13-9128-gd166c3ecf633a939777d02bc5c9ad4e2449e6d98
Author: Jonathan Wakely 
Date:   Wed Jul 10 10:29:52 2024 +0100

libstdc++: Use direct-initialization for std::vector's allocator 
[PR115854]

The consensus in the standard committee is that this change shouldn't be
necessary, and the Allocator requirements should require conversions
between rebound allocators to be implicit. But we can make it work for
now anyway.

libstdc++-v3/ChangeLog:

PR libstdc++/115854
* include/bits/stl_bvector.h (_Bvector_base): Convert allocator
to rebound type explicitly.
* testsuite/23_containers/vector/allocator/115854.cc: New test.
* testsuite/23_containers/vector/bool/allocator/115854.cc: New test.

(cherry picked from commit c5efc6eca8e3eee7038ae218cf7e2dbe9ed9d82a)

Diff:
---
 libstdc++-v3/include/bits/stl_bvector.h|  2 +-
 .../testsuite/23_containers/vector/allocator/115854.cc | 10 ++
 .../testsuite/23_containers/vector/bool/allocator/115854.cc| 10 ++
 3 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/bits/stl_bvector.h 
b/libstdc++-v3/include/bits/stl_bvector.h
index 63e416053e0f..a8fdc7bc4255 100644
--- a/libstdc++-v3/include/bits/stl_bvector.h
+++ b/libstdc++-v3/include/bits/stl_bvector.h
@@ -654,7 +654,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 
   _GLIBCXX20_CONSTEXPR
   _Bvector_base(const allocator_type& __a)
-  : _M_impl(__a) { }
+  : _M_impl(_Bit_alloc_type(__a)) { }
 
 #if __cplusplus >= 201103L
   _Bvector_base(_Bvector_base&&) = default;
diff --git a/libstdc++-v3/testsuite/23_containers/vector/allocator/115854.cc 
b/libstdc++-v3/testsuite/23_containers/vector/allocator/115854.cc
new file mode 100644
index ..6c9016b311f2
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/allocator/115854.cc
@@ -0,0 +1,10 @@
+// { dg-do compile { target c++11 } }
+
+#include 
+#include 
+
+__gnu_test::ExplicitConsAlloc alloc;
+std::vector> v;
+std::vector> v1(alloc);
+std::vector> v2(v1, alloc);
+std::vector> v3(std::move(v1), alloc);
diff --git 
a/libstdc++-v3/testsuite/23_containers/vector/bool/allocator/115854.cc 
b/libstdc++-v3/testsuite/23_containers/vector/bool/allocator/115854.cc
new file mode 100644
index ..14b28cc3e964
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/bool/allocator/115854.cc
@@ -0,0 +1,10 @@
+// { dg-do compile { target c++11 } }
+
+#include 
+#include 
+
+__gnu_test::ExplicitConsAlloc alloc;
+std::vector> v;
+std::vector> v1(alloc);
+std::vector> v2(v1, alloc);
+std::vector> v3(std::move(v1), 
alloc);


[gcc r13-9120] libstdc++: Tweak %c formatting for chrono types

2024-10-17 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:cc8c7e44145deb457dbe436cf8b5bd88da0a9ec3

commit r13-9120-gcc8c7e44145deb457dbe436cf8b5bd88da0a9ec3
Author: Jonathan Wakely 
Date:   Fri Sep 27 16:54:31 2024 +0100

libstdc++: Tweak %c formatting for chrono types

libstdc++-v3/ChangeLog:

* include/bits/chrono_io.h (__formatter_chrono::_M_c): Add
[[unlikely]] attribute to condition for missing %c format in
locale. Use %T instead of %H:%M:%S in fallback.

(cherry picked from commit ce89d2f3170e0d6474cee2c5cb9d478426a5b2f6)

Diff:
---
 libstdc++-v3/include/bits/chrono_io.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/bits/chrono_io.h 
b/libstdc++-v3/include/bits/chrono_io.h
index 37ede63a53eb..db46bfc68e87 100644
--- a/libstdc++-v3/include/bits/chrono_io.h
+++ b/libstdc++-v3/include/bits/chrono_io.h
@@ -794,8 +794,8 @@ namespace __format
  const _CharT* __formats[2];
  __tp._M_date_time_formats(__formats);
  const _CharT* __rep = __formats[__mod];
- if (!*__rep)
-   __rep = _GLIBCXX_WIDEN("%a %b %e %H:%M:%S %Y");
+ if (!*__rep) [[unlikely]]
+   __rep = _GLIBCXX_WIDEN("%a %b %e %T %Y");
  basic_string<_CharT> __fmt(_S_empty_spec);
  __fmt.insert(1u, 1u, _S_colon);
  __fmt.insert(2u, __rep);


[gcc r14-10795] libstdc++: Fix Python deprecation warning in printers.py

2024-10-16 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:23480efbab9212adb3a0147a3e5dd93d53e1843b

commit r14-10795-g23480efbab9212adb3a0147a3e5dd93d53e1843b
Author: Jonathan Wakely 
Date:   Wed Oct 16 09:22:37 2024 +0100

libstdc++: Fix Python deprecation warning in printers.py

python/libstdcxx/v6/printers.py:1355: DeprecationWarning: 'count' is passed 
as positional argument

The Python docs say:

  Deprecated since version 3.13: Passing count and flags as positional
  arguments is deprecated. In future Python versions they will be
  keyword-only parameters.

Using a keyword argument for count only became possible with Python 3.1
so introduce a new function to do the substitution.

libstdc++-v3/ChangeLog:

* python/libstdcxx/v6/printers.py (strip_fundts_namespace): New.
(StdExpAnyPrinter, StdExpOptionalPrinter): Use it.

(cherry picked from commit b9e98bb9919fa9f07782f23f79b3d35abb9ff542)

Diff:
---
 libstdc++-v3/python/libstdcxx/v6/printers.py | 19 +--
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py 
b/libstdc++-v3/python/libstdcxx/v6/printers.py
index a6c2ed4599fa..3026de35bbd2 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -220,6 +220,16 @@ def strip_versioned_namespace(typename):
 return typename.replace(_versioned_namespace, '')
 
 
+def strip_fundts_namespace(typ):
+"""Remove "fundamentals_vN" inline namespace from qualified type name."""
+pattern = r'^std::experimental::fundamentals_v\d::'
+repl = 'std::experimental::'
+if sys.version_info[0] == 2:
+return re.sub(pattern, repl, typ, 1)
+else: # Technically this needs Python 3.1 but nobody should be using 3.0
+return re.sub(pattern, repl, typ, count=1)
+
+
 def strip_inline_namespaces(type_str):
 """Remove known inline namespaces from the canonical name of a type."""
 type_str = strip_versioned_namespace(type_str)
@@ -1352,8 +1362,7 @@ class StdExpAnyPrinter(SingleObjContainerPrinter):
 
 def __init__(self, typename, val):
 self._typename = strip_versioned_namespace(typename)
-self._typename = re.sub(r'^std::experimental::fundamentals_v\d::',
-'std::experimental::', self._typename, 1)
+self._typename = strip_fundts_namespace(self._typename)
 self._val = val
 self._contained_type = None
 contained_value = None
@@ -1446,10 +1455,8 @@ class StdExpOptionalPrinter(SingleObjContainerPrinter):
 """Print a std::optional or std::experimental::optional."""
 
 def __init__(self, typename, val):
-typename = strip_versioned_namespace(typename)
-self._typename = re.sub(
-r'^std::(experimental::|)(fundamentals_v\d::|)(.*)',
-r'std::\1\3', typename, 1)
+self._typename = strip_versioned_namespace(typename)
+self._typename = strip_fundts_namespace(self._typename)
 payload = val['_M_payload']
 if self._typename.startswith('std::experimental'):
 engaged = val['_M_engaged']


[gcc r14-10794] libstdc++: Increase timeouts for PSTL tests in debug mode [PR90276]

2024-10-16 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:f1cee9d1a049a3bc7cae24245fcc3c415fd12764

commit r14-10794-gf1cee9d1a049a3bc7cae24245fcc3c415fd12764
Author: Jonathan Wakely 
Date:   Wed Jun 12 17:11:23 2024 +0100

libstdc++: Increase timeouts for PSTL tests in debug mode [PR90276]

These tests compile very slowly in debug mode.

libstdc++-v3/ChangeLog:

PR libstdc++/90276
* 
testsuite/25_algorithms/pstl/alg_modifying_operations/rotate_copy.cc:
Increase timeout for debug mode.
* 
testsuite/25_algorithms/pstl/alg_modifying_operations/transform_binary.cc:
Likewise.
* testsuite/25_algorithms/pstl/alg_nonmodifying/mismatch.cc:
Likewise.
* 
testsuite/25_algorithms/pstl/alg_sorting/lexicographical_compare.cc:
Likewise.
* testsuite/25_algorithms/pstl/alg_sorting/minmax_element.cc:
Likewise.
* 
testsuite/25_algorithms/pstl/alg_sorting/set_symmetric_difference.cc:
Likewise.

(cherry picked from commit e65b6627a36869b01bbe128a5324e4b415b28880)

Diff:
---
 .../testsuite/25_algorithms/pstl/alg_modifying_operations/rotate_copy.cc | 1 +
 .../25_algorithms/pstl/alg_modifying_operations/transform_binary.cc  | 1 +
 libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/mismatch.cc   | 1 +
 .../testsuite/25_algorithms/pstl/alg_sorting/lexicographical_compare.cc  | 1 +
 libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/minmax_element.cc  | 1 +
 .../testsuite/25_algorithms/pstl/alg_sorting/set_symmetric_difference.cc | 1 +
 6 files changed, 6 insertions(+)

diff --git 
a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/rotate_copy.cc
 
b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/rotate_copy.cc
index ea647c6c23a0..1b788e1b7ee5 100644
--- 
a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/rotate_copy.cc
+++ 
b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/rotate_copy.cc
@@ -2,6 +2,7 @@
 // { dg-options "-ltbb" }
 // { dg-do run { target c++17 } }
 // { dg-timeout-factor 3 }
+// { dg-timeout-factor 5 { target debug_mode } }
 // { dg-require-effective-target tbb_backend }
 
 //===-- rotate_copy.pass.cpp 
--===//
diff --git 
a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/transform_binary.cc
 
b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/transform_binary.cc
index 1f5f239a94be..16b815c5d514 100644
--- 
a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/transform_binary.cc
+++ 
b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_modifying_operations/transform_binary.cc
@@ -2,6 +2,7 @@
 // { dg-options "-ltbb" }
 // { dg-do run { target c++17 } }
 // { dg-timeout-factor 3 }
+// { dg-timeout-factor 5 { target debug_mode } }
 // { dg-require-effective-target tbb_backend }
 
 //===-- transform_binary.pass.cpp 
-===//
diff --git 
a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/mismatch.cc 
b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/mismatch.cc
index 1173186f65c0..441f5d1e3782 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/mismatch.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_nonmodifying/mismatch.cc
@@ -2,6 +2,7 @@
 // { dg-options "-ltbb" }
 // { dg-do run { target c++17 } }
 // { dg-timeout-factor 3 }
+// { dg-timeout-factor 5 { target debug_mode } }
 // { dg-require-effective-target tbb_backend }
 
 //===-- mismatch.pass.cpp 
-===//
diff --git 
a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/lexicographical_compare.cc
 
b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/lexicographical_compare.cc
index 924aa78652e8..78edeb025d78 100644
--- 
a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/lexicographical_compare.cc
+++ 
b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/lexicographical_compare.cc
@@ -2,6 +2,7 @@
 // { dg-options "-ltbb" }
 // { dg-do run { target c++17 } }
 // { dg-timeout-factor 3 }
+// { dg-timeout-factor 5 { target debug_mode } }
 // { dg-require-effective-target tbb_backend }
 
 //===-- lexicographical_compare.pass.cpp 
--===//
diff --git 
a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/minmax_element.cc 
b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/minmax_element.cc
index 0a9f41ca1797..e4bd435d1926 100644
--- a/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/minmax_element.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/pstl/alg_sorting/minmax_element.cc
@@ -2,6 +2,7 @@
 // { dg-options "-ltbb" }
 // { dg-do run { target c++17 } }
 // { dg-timeout-factor 3 }
+// { dg-timeout-factor 5 { target debug_mode } }
 // { dg-require-effective-target tbb_backend }
 
 //===-- minmax_element.pass.cpp 
--

[gcc r14-10793] libstdc++: Implement LWG 3564 for ranges::transform_view

2024-10-16 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:4d8a55ac552627ebf9bf50d28a35459cba58d8c6

commit r14-10793-g4d8a55ac552627ebf9bf50d28a35459cba58d8c6
Author: Jonathan Wakely 
Date:   Sun Oct 13 21:47:14 2024 +0100

libstdc++: Implement LWG 3564 for ranges::transform_view

The _Iterator type returned by begin() const uses const F& to
transform the elements, so it should use const F& to determine the
iterator's value_type and iterator_category as well.

This was accepted into the WP in July 2022.

libstdc++-v3/ChangeLog:

* include/std/ranges (transform_view:_Iterator): Use const F&
to determine value_type and iterator_category of
_Iterator, as per LWG 3564.
* testsuite/std/ranges/adaptors/transform.cc: Check value_type
and iterator_category.

Reviewed-by: Patrick Palka 
(cherry picked from commit dde19c600c3c8a1d765c9b4961d2556e89edad14)

Diff:
---
 libstdc++-v3/include/std/ranges   |  9 +++--
 .../testsuite/std/ranges/adaptors/transform.cc| 19 +++
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index 59a251536208..2c8a8535d396 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -1870,8 +1870,12 @@ namespace views::__adaptor
  static auto
  _S_iter_cat()
  {
+   // _GLIBCXX_RESOLVE_LIB_DEFECTS
+   // 3564. transform_view::iterator::value_type and
+   // iterator_category should use const F&
using _Base = transform_view::_Base<_Const>;
-   using _Res = invoke_result_t<_Fp&, range_reference_t<_Base>>;
+   using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
+range_reference_t<_Base>>;
if constexpr (is_lvalue_reference_v<_Res>)
  {
using _Cat
@@ -1920,7 +1924,8 @@ namespace views::__adaptor
  using iterator_concept = decltype(_S_iter_concept());
  // iterator_category defined in __transform_view_iter_cat
  using value_type
-   = remove_cvref_t>>;
+   = remove_cvref_t&,
+range_reference_t<_Base>>>;
  using difference_type = range_difference_t<_Base>;
 
  _Iterator() requires default_initializable<_Base_iter> = default;
diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc 
b/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc
index bcb18a3fc6c8..ca695349650a 100644
--- a/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc
+++ b/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc
@@ -196,6 +196,24 @@ test09()
 #endif
 }
 
+void
+test10()
+{
+  struct F {
+short operator()(int) { return 0; }
+const int& operator()(const int& i) const { return i; }
+  };
+
+  int x[] {2, 4};
+  const auto xform = x | views::transform(F{});
+  using const_iterator = decltype(xform.begin());
+  // LWG 3564. transform_view::iterator::value_type and iterator_category
+  // should use const F&
+  static_assert(std::same_as, int>);
+  using cat = std::iterator_traits::iterator_category;
+  static_assert(std::same_as);
+}
+
 int
 main()
 {
@@ -208,4 +226,5 @@ main()
   test07();
   test08();
   test09();
+  test10();
 }


[gcc r15-4338] libstdc++: Populate generic std::time_get's wide %c format [PR117135]

2024-10-14 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:707d84efee7f7eb5a336935f386e094402f267a6

commit r15-4338-g707d84efee7f7eb5a336935f386e094402f267a6
Author: Jonathan Wakely 
Date:   Tue Sep 24 23:20:56 2024 +0100

libstdc++: Populate generic std::time_get's wide %c format [PR117135]

I missed out the __timepunct specialization for the "generic"
implementation when defining the %c format in r15-4016-gc534e37faccf48.

libstdc++-v3/ChangeLog:

PR libstdc++/117135
* config/locale/generic/time_members.cc
(__timepunct::_M_initialize_timepunc): Set
_M_date_time_format for C locale. Set %Ex formats to the same
values as the %x formats.

Diff:
---
 libstdc++-v3/config/locale/generic/time_members.cc | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/libstdc++-v3/config/locale/generic/time_members.cc 
b/libstdc++-v3/config/locale/generic/time_members.cc
index 6619f0ca881a..5012a270dd1a 100644
--- a/libstdc++-v3/config/locale/generic/time_members.cc
+++ b/libstdc++-v3/config/locale/generic/time_members.cc
@@ -150,11 +150,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_data = new __timepunct_cache;
 
   _M_data->_M_date_format = L"%m/%d/%y";
-  _M_data->_M_date_era_format = L"%m/%d/%y";
+  _M_data->_M_date_era_format = _M_data->_M_date_format;
   _M_data->_M_time_format = L"%H:%M:%S";
-  _M_data->_M_time_era_format = L"%H:%M:%S";
-  _M_data->_M_date_time_format = L"";
-  _M_data->_M_date_time_era_format = L"";
+  _M_data->_M_time_era_format = _M_data->_M_time_format;
+  _M_data->_M_date_time_format = L"%a %b %e %T %Y";
+  _M_data->_M_date_time_era_format = _M_data->_M_date_time_format;
   _M_data->_M_am = L"AM";
   _M_data->_M_pm = L"PM";
   _M_data->_M_am_pm_format = L"%I:%M:%S %p";


[gcc r15-4320] libstdc++: Enable memcpy optimizations for distinct integral types [PR93059]

2024-10-14 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:308d19c11e119b2c5abf67778dd0ac8a370e5df7

commit r15-4320-g308d19c11e119b2c5abf67778dd0ac8a370e5df7
Author: Jonathan Wakely 
Date:   Thu Oct 10 13:36:33 2024 +0100

libstdc++: Enable memcpy optimizations for distinct integral types [PR93059]

Currently we only optimize std::copy, std::copy_n etc. to memmove when
the source and destination types are the same. This means that we fail
to optimize copying between distinct 1-byte types, e.g. copying from a
buffer of unsigned char to a buffer of char8_t or vice versa.

This patch adds more partial specializations of the __memcpyable trait
so that we allow memcpy between integers of equal widths. This will
enable memmove for copies between narrow character types and also
between same-width types like int and unsigned.

Enabling the optimization needs to be based on the width of the integer
type, not just the size in bytes. This is because some targets define
non-standard integral types such as __int20 in msp430, which has padding
bits. It would not be safe to memcpy between e.g. __int20 and int32_t,
even though sizeof(__int20) == sizeof(int32_t). A new trait is
introduced to define the width, __memcpyable_integer, and then the
__memcpyable trait compares the widths.

It's safe to copy between signed and unsigned integers of the same
width, because GCC only supports two's complement integers.

I initially though it would be useful to define the specialization
__memcpyable_integer to enable copying between narrow character
types and std::byte. But that isn't possible with std::copy, because
is_assignable is false. Optimized copies using memmove
will already happen for copying std::byte to std::byte, because
__memcpyable is true.

libstdc++-v3/ChangeLog:

PR libstdc++/93059
* include/bits/cpp_type_traits.h (__memcpyable): Add partial
specialization for pointers to distinct types.
(__memcpyable_integer): New trait to control which types can use
cross-type memcpy optimizations.

Diff:
---
 libstdc++-v3/include/bits/cpp_type_traits.h | 89 -
 1 file changed, 87 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/bits/cpp_type_traits.h 
b/libstdc++-v3/include/bits/cpp_type_traits.h
index 060652afb183..2f9ce75e82c2 100644
--- a/libstdc++-v3/include/bits/cpp_type_traits.h
+++ b/libstdc++-v3/include/bits/cpp_type_traits.h
@@ -434,8 +434,6 @@ __INT_N(__GLIBCXX_TYPE_INT_N_3)
 };
 #endif
 
-  template struct iterator_traits;
-
   // A type that is safe for use with memcpy, memmove, memcmp etc.
   template
 struct __is_nonvolatile_trivially_copyable
@@ -459,16 +457,103 @@ __INT_N(__GLIBCXX_TYPE_INT_N_3)
   enum { __value = 0 };
 };
 
+  // Allow memcpy when source and destination are pointers to the same type.
   template
 struct __memcpyable<_Tp*, _Tp*>
 : __is_nonvolatile_trivially_copyable<_Tp>
 { };
 
+  // Source pointer can be const.
   template
 struct __memcpyable<_Tp*, const _Tp*>
 : __is_nonvolatile_trivially_copyable<_Tp>
 { };
 
+  template struct __memcpyable_integer;
+
+  // For heterogeneous types, allow memcpy between equal-sized integers.
+  template
+struct __memcpyable<_Tp*, _Up*>
+{
+  enum {
+   __value = __memcpyable_integer<_Tp>::__width != 0
+   && ((int)__memcpyable_integer<_Tp>::__width
+ == (int)__memcpyable_integer<_Up>::__width)
+  };
+};
+
+  // Specialization for const U* because __is_integer is never true.
+  template
+struct __memcpyable<_Tp*, const _Up*>
+: __memcpyable<_Tp*, _Up*>
+{ };
+
+  template
+struct __memcpyable_integer
+{
+  enum {
+   __width = __is_integer<_Tp>::__value ? (sizeof(_Tp) * __CHAR_BIT__) : 0
+  };
+};
+
+  // Cannot memcpy volatile memory.
+  template
+struct __memcpyable_integer
+{ enum { __width = 0 }; };
+
+  // Specializations for __intNN types with padding bits.
+#if defined __GLIBCXX_TYPE_INT_N_0 && __GLIBCXX_BITSIZE_INT_N_0 % __CHAR_BIT__
+  __extension__
+  template<>
+struct __memcpyable_integer<__GLIBCXX_TYPE_INT_N_0>
+{ enum { __width = __GLIBCXX_BITSIZE_INT_N_0 }; };
+  __extension__
+  template<>
+struct __memcpyable_integer
+{ enum { __width = __GLIBCXX_BITSIZE_INT_N_0 }; };
+#endif
+#if defined __GLIBCXX_TYPE_INT_N_1 && __GLIBCXX_BITSIZE_INT_N_1 % __CHAR_BIT__
+  __extension__
+  template<>
+struct __memcpyable_integer<__GLIBCXX_TYPE_INT_N_1>
+{ enum { __width = __GLIBCXX_BITSIZE_INT_N_1 }; };
+  __extension__
+  template<>
+struct __memcpyable_integer
+{ enum { __width = __GLIBCXX_BITSIZE_INT_N_1 }; };
+#endif
+#if defined __GLIBCXX_TYPE_INT_N_2 && __GLIBCXX_BITSIZE_INT_N_2 % __CHAR_BIT__
+  __extension__
+  template<>
+struct __memcpyable_integer<__GLIBCXX_TYPE_INT_N_2>
+

[gcc r15-4303] libstdc++: Fix ranges::copy_backward for a single memcpyable element [PR117121]

2024-10-13 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:27f6b376e8e196c7c85c8b47436cd2f2993768da

commit r15-4303-g27f6b376e8e196c7c85c8b47436cd2f2993768da
Author: Jonathan Wakely 
Date:   Sun Oct 13 19:14:04 2024 +0100

libstdc++: Fix ranges::copy_backward for a single memcpyable element 
[PR117121]

The result iterator needs to be decremented before writing to it.

Improve the PR 108846 tests for all of std::copy, std::copy_n,
std::copy_backward, and the std::ranges versions.

libstdc++-v3/ChangeLog:

PR libstdc++/117121
* include/bits/ranges_algobase.h (copy_backward): Decrement
output iterator before assigning one element through it.
* testsuite/25_algorithms/copy/108846.cc: Ensure the algorithm's
effects are correct for a single memcpyable element.
* testsuite/25_algorithms/copy_backward/108846.cc: Likewise.
* testsuite/25_algorithms/copy_n/108846.cc: Likewise.

Diff:
---
 libstdc++-v3/include/bits/ranges_algobase.h   |  5 +++--
 libstdc++-v3/testsuite/25_algorithms/copy/108846.cc   | 15 +++
 .../testsuite/25_algorithms/copy_backward/108846.cc   | 15 +++
 libstdc++-v3/testsuite/25_algorithms/copy_n/108846.cc | 15 +++
 4 files changed, 48 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/bits/ranges_algobase.h 
b/libstdc++-v3/include/bits/ranges_algobase.h
index 40c628b38182..3c8d46198c5d 100644
--- a/libstdc++-v3/include/bits/ranges_algobase.h
+++ b/libstdc++-v3/include/bits/ranges_algobase.h
@@ -418,12 +418,13 @@ namespace ranges
{
  using _ValueTypeI = iter_value_t<_Iter>;
  auto __num = __last - __first;
+ __result -= __num;
  if (__num > 1) [[likely]]
-   __builtin_memmove(__result - __num, __first,
+   __builtin_memmove(__result, __first,
  sizeof(_ValueTypeI) * __num);
  else if (__num == 1)
ranges::__assign_one<_IsMove>(__first, __result);
- return {__first + __num, __result - __num};
+ return {__first + __num, __result};
}
}
 
diff --git a/libstdc++-v3/testsuite/25_algorithms/copy/108846.cc 
b/libstdc++-v3/testsuite/25_algorithms/copy/108846.cc
index e3b722c068ab..a283e6fcd9fb 100644
--- a/libstdc++-v3/testsuite/25_algorithms/copy/108846.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/copy/108846.cc
@@ -25,10 +25,15 @@ test_pr108846()
 B *src = &dsrc;
 // If this is optimized to memmove it will overwrite tail padding.
 std::copy(src, src+1, dst);
+// Check tail padding is unchanged:
 VERIFY(ddst.x == 3);
+// Check B subobject was copied:
+VERIFY(ddst.i == 4 && ddst.j == 5);
 #if __cpp_lib_ranges >= 201911L
+ddst.i = ddst.j = 99;
 std::ranges::copy(src, src+1, dst);
 VERIFY(ddst.x == 3);
+VERIFY(ddst.i == 4 && ddst.j == 5);
 #endif
 }
 
@@ -52,10 +57,15 @@ test_non_const_copy_assign()
 B2 *src = &dsrc;
 // Ensure the not-taken trivial copy path works for this type.
 std::copy(src, src+1, dst);
+// Check tail padding is unchanged:
 VERIFY(ddst.x == 3);
+// Check B subobject was copied:
+VERIFY(ddst.i == 4 && ddst.j == 5);
 #if __cpp_lib_ranges >= 201911L
+ddst.i = ddst.j = 99;
 std::ranges::copy(src, src+1, dst);
 VERIFY(ddst.x == 3);
+VERIFY(ddst.i == 4 && ddst.j == 5);
 #endif
 }
 
@@ -81,10 +91,15 @@ test_non_const_copy_assign_trivial()
 B3 *src = &dsrc;
 // If this is optimized to memmove it will overwrite tail padding.
 std::copy(src, src+1, dst);
+// Check tail padding is unchanged:
 VERIFY(ddst.x == 3);
+// Check B subobject was copied:
+VERIFY(ddst.i == 4 && ddst.j == 5);
 #if __cpp_lib_ranges >= 201911L
+ddst.i = ddst.j = 99;
 std::ranges::copy(src, src+1, dst);
 VERIFY(ddst.x == 3);
+VERIFY(ddst.i == 4 && ddst.j == 5);
 #endif
 }
 
diff --git a/libstdc++-v3/testsuite/25_algorithms/copy_backward/108846.cc 
b/libstdc++-v3/testsuite/25_algorithms/copy_backward/108846.cc
index 206748d92d33..855ee3e182f7 100644
--- a/libstdc++-v3/testsuite/25_algorithms/copy_backward/108846.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/copy_backward/108846.cc
@@ -25,10 +25,15 @@ test_pr108846()
 B *src = &dsrc;
 // If this is optimized to memmove it will overwrite tail padding.
 std::copy_backward(src, src+1, dst+1);
+// Check tail padding is unchanged:
 VERIFY(ddst.x == 3);
+// Check B subobject was copied:
+VERIFY(ddst.i == 4 && ddst.j == 5);
 #if __cpp_lib_ranges >= 201911L
+ddst.i = ddst.j = 99;
 std::ranges::copy_backward(src, src+1, dst+1);
 VERIFY(ddst.x == 3);
+VERIFY(ddst.i == 4 && ddst.j == 5);
 #endif
 }
 
@@ -52,10 +57,15 @@ test_non_const_copy_assign()
 B2 *src = &dsrc;
 // Ensure the not-taken trivial copy path works 

[gcc r15-4211] libstdc++: Ignore _GLIBCXX_USE_POSIX_SEMAPHORE if not supported [PR116992]

2024-10-09 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:9a5ac633f0f49c819f2745584475051c9eb8f6e0

commit r15-4211-g9a5ac633f0f49c819f2745584475051c9eb8f6e0
Author: Jonathan Wakely 
Date:   Mon Oct 7 10:22:24 2024 +0100

libstdc++: Ignore _GLIBCXX_USE_POSIX_SEMAPHORE if not supported [PR116992]

If _GLIBCXX_HAVE_POSIX_SEMAPHRE is undefined then users get an error
when defining _GLIBCXX_USE_POSIX_SEMAPHORE. We can just ignore it
instead (and warn them it's being ignored).

This fixes a testsuite failure on hppa64-hp-hpux11.11 (and probably some
other targets):

FAIL: 30_threads/semaphore/platform_try_acquire_for.cc  -std=gnu++20 (test 
for excess errors)
Excess errors:
semaphore:49: error: '__semaphore_impl' has not been declared

libstdc++-v3/ChangeLog:

PR libstdc++/116992
* include/bits/semaphore_base.h (_GLIBCXX_USE_POSIX_SEMAPHORE):
Undefine and issue a warning if POSIX sem_t is not supported.
* testsuite/30_threads/semaphore/platform_try_acquire_for.cc:
Prune new warning.

Diff:
---
 libstdc++-v3/include/bits/semaphore_base.h | 3 +++
 .../testsuite/30_threads/semaphore/platform_try_acquire_for.cc | 2 ++
 2 files changed, 5 insertions(+)

diff --git a/libstdc++-v3/include/bits/semaphore_base.h 
b/libstdc++-v3/include/bits/semaphore_base.h
index 9d73b37e60a1..dd16d2c92498 100644
--- a/libstdc++-v3/include/bits/semaphore_base.h
+++ b/libstdc++-v3/include/bits/semaphore_base.h
@@ -45,6 +45,9 @@
 # include  // errno, EINTR, EAGAIN etc.
 # include// SEM_VALUE_MAX
 # include // sem_t, sem_init, sem_wait, sem_post etc.
+#elif defined(_GLIBCXX_USE_POSIX_SEMAPHORE)
+# warning "POSIX semaphore not available, ignoring 
_GLIBCXX_USE_POSIX_SEMAPHORE"
+# undef _GLIBCXX_USE_POSIX_SEMAPHORE
 #endif
 
 namespace std _GLIBCXX_VISIBILITY(default)
diff --git 
a/libstdc++-v3/testsuite/30_threads/semaphore/platform_try_acquire_for.cc 
b/libstdc++-v3/testsuite/30_threads/semaphore/platform_try_acquire_for.cc
index bf6cd142bf01..6d90564ea8ac 100644
--- a/libstdc++-v3/testsuite/30_threads/semaphore/platform_try_acquire_for.cc
+++ b/libstdc++-v3/testsuite/30_threads/semaphore/platform_try_acquire_for.cc
@@ -5,3 +5,5 @@
 // { dg-add-options libatomic }
 
 #include "try_acquire_for.cc"
+
+// { dg-prune-output "ignoring _GLIBCXX_USE_POSIX_SEMAPHORE" }


[gcc r15-4210] libstdc++: Fix -Wnarrowing in [PR116991]

2024-10-09 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:e998014d1b14592c43b0f655793011c6395ff02a

commit r15-4210-ge998014d1b14592c43b0f655793011c6395ff02a
Author: Jonathan Wakely 
Date:   Mon Oct 7 10:19:29 2024 +0100

libstdc++: Fix -Wnarrowing in  [PR116991]

When _GLIBCXX_USE_C99_COMPLEX_ARC is undefined we use the generic
__complex_acos function template for _Float32 etc. and that gives a
-Wnarrowing warning:

complex:2043: warning: ISO C++ does not allow converting to '_Float32' from 
'long double' with greater conversion rank [-Wnarrowing]

Use a cast to do the conversion so that it doesn't warn.

libstdc++-v3/ChangeLog:

PR libstdc++/116991
* include/std/complex (__complex_acos): Cast literal to
destination type.

Diff:
---
 libstdc++-v3/include/std/complex | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/complex b/libstdc++-v3/include/std/complex
index 5bc6618f7de0..eb89e3a8bcfb 100644
--- a/libstdc++-v3/include/std/complex
+++ b/libstdc++-v3/include/std/complex
@@ -2040,7 +2040,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 __complex_acos(const std::complex<_Tp>& __z)
 {
   const std::complex<_Tp> __t = std::asin(__z);
-  const _Tp __pi_2 = 1.5707963267948966192313216916397514L;
+  const _Tp __pi_2 = (_Tp) 1.5707963267948966192313216916397514L;
   return std::complex<_Tp>(__pi_2 - __t.real(), -__t.imag());
 }


[gcc r15-4206] libstdc++: Do not cast away const-ness in std::construct_at (LWG 3870)

2024-10-09 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:2eaae1bd69302efe6d73d8d63739b081299f8641

commit r15-4206-g2eaae1bd69302efe6d73d8d63739b081299f8641
Author: Jonathan Wakely 
Date:   Thu Jul 11 20:38:05 2024 +0100

libstdc++: Do not cast away const-ness in std::construct_at (LWG 3870)

This change also requires implementing the proposed resolution of LWG
3216 so that std::make_shared and std::allocate_shared still work, and
the proposed resolution of LWG 3891 so that std::expected still works.

libstdc++-v3/ChangeLog:

* include/bits/shared_ptr_base.h: Remove cv-qualifiers from
type managed by _Sp_counted_ptr_inplace, as per LWG 3210.
* include/bits/stl_construct.h: Do not cast away cv-qualifiers
when passing pointer to placement new.
* include/std/expected: Use remove_cv_t for union member, as per
LWG 3891.
* testsuite/20_util/allocator/void.cc: Do not test construction
via const pointer.

Diff:
---
 libstdc++-v3/include/bits/shared_ptr_base.h  | 15 ---
 libstdc++-v3/include/bits/stl_construct.h|  6 +++---
 libstdc++-v3/include/std/expected|  2 +-
 libstdc++-v3/testsuite/20_util/allocator/void.cc | 15 ---
 4 files changed, 12 insertions(+), 26 deletions(-)

diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h 
b/libstdc++-v3/include/bits/shared_ptr_base.h
index 3d0b74ba1c6e..ef0658f61828 100644
--- a/libstdc++-v3/include/bits/shared_ptr_base.h
+++ b/libstdc++-v3/include/bits/shared_ptr_base.h
@@ -591,7 +591,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
_Alloc& _M_alloc() noexcept { return _A_base::_S_get(*this); }
 
-   __gnu_cxx::__aligned_buffer<_Tp> _M_storage;
+   __gnu_cxx::__aligned_buffer<__remove_cv_t<_Tp>> _M_storage;
   };
 
 public:
@@ -633,7 +633,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   virtual void*
   _M_get_deleter(const std::type_info& __ti) noexcept override
   {
-   auto __ptr = const_cast::type*>(_M_ptr());
// Check for the fake type_info first, so we don't try to access it
// as a real type_info object. Otherwise, check if it's the real
// type_info for this class. With RTTI enabled we can check directly,
@@ -646,11 +645,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Sp_make_shared_tag::_S_eq(__ti)
 #endif
   )
- return __ptr;
+ return _M_ptr();
return nullptr;
   }
 
-  _Tp* _M_ptr() noexcept { return _M_impl._M_storage._M_ptr(); }
+  __remove_cv_t<_Tp>*
+  _M_ptr() noexcept { return _M_impl._M_storage._M_ptr(); }
 
   _Impl _M_impl;
 };
@@ -674,13 +674,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   [[no_unique_address]] _Alloc _M_alloc;
 
   union {
-   _Tp _M_obj;
+   remove_cv_t<_Tp> _M_obj;
char _M_unused;
   };
 
   friend class __shared_count<_Lp>; // To be able to call _M_ptr().
 
-  _Tp* _M_ptr() noexcept { return std::__addressof(_M_obj); }
+  auto _M_ptr() noexcept { return std::__addressof(_M_obj); }
 
 public:
   using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_ptr_inplace>;
@@ -962,7 +962,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__shared_count(_Tp*& __p, _Sp_alloc_shared_tag<_Alloc> __a,
   _Args&&... __args)
{
- typedef _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> _Sp_cp_type;
+ using _Tp2 = __remove_cv_t<_Tp>;
+ using _Sp_cp_type = _Sp_counted_ptr_inplace<_Tp2, _Alloc, _Lp>;
  typename _Sp_cp_type::__allocator_type __a2(__a._M_a);
  auto __guard = std::__allocate_guarded(__a2);
  _Sp_cp_type* __mem = __guard.get();
diff --git a/libstdc++-v3/include/bits/stl_construct.h 
b/libstdc++-v3/include/bits/stl_construct.h
index 146ea14e99ad..9d6111396e1c 100644
--- a/libstdc++-v3/include/bits/stl_construct.h
+++ b/libstdc++-v3/include/bits/stl_construct.h
@@ -96,7 +96,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 construct_at(_Tp* __location, _Args&&... __args)
 noexcept(noexcept(::new((void*)0) _Tp(std::declval<_Args>()...)))
 {
-  void* __loc = const_cast*>(__location);
+  void* __loc = __location;
   // _GLIBCXX_RESOLVE_LIB_DEFECTS
   // 3436. std::construct_at should support arrays
   if constexpr (is_array_v<_Tp>)
@@ -130,7 +130,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  return;
}
 #endif
-  ::new((void*)__p) _Tp(std::forward<_Args>(__args)...);
+  ::new(static_cast(__p)) _Tp(std::forward<_Args>(__args)...);
 }
 #else
   template
@@ -146,7 +146,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 inline void
 _Construct_novalue(_T1* __p)
-{ ::new((void*)__p) _T1; }
+{ ::new(static_cast(__p)) _T1; }
 
   template
 _GLIBCXX20_CONSTEXPR void
diff --git a/libstdc++-v3/include/std/expected 
b/libstdc++-v3/include/std/expected
index 9e92339e4066..d4a4bc175415 100644
--- a/libstdc++-v3/include/std/expected
+++ b/li

[gcc r15-4205] libstdc++: Make std::construct_at support arrays (LWG 3436)

2024-10-09 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:993deb3a9a4eb78b05587f9b2f9d83a4ccc60c74

commit r15-4205-g993deb3a9a4eb78b05587f9b2f9d83a4ccc60c74
Author: Jonathan Wakely 
Date:   Mon Mar 18 16:59:50 2024 +

libstdc++: Make std::construct_at support arrays (LWG 3436)

The issue was approved at the recent St. Louis meeting, requiring
support for bounded arrays, but only without arguments to initialize the
array elements.

libstdc++-v3/ChangeLog:

* include/bits/stl_construct.h (construct_at): Support array
types (LWG 3436).
* testsuite/20_util/specialized_algorithms/construct_at/array.cc:
New test.
* 
testsuite/20_util/specialized_algorithms/construct_at/array_neg.cc:
New test.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/initlist-opt1.C: Adjust for different diagnostics
from std::construct_at by adding -fconcepts-diagnostics-depth=2.

Diff:
---
 gcc/testsuite/g++.dg/cpp0x/initlist-opt1.C |  1 +
 libstdc++-v3/include/bits/stl_construct.h  | 20 +--
 .../specialized_algorithms/construct_at/array.cc   | 41 ++
 .../construct_at/array_neg.cc  | 19 ++
 4 files changed, 78 insertions(+), 3 deletions(-)

diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-opt1.C 
b/gcc/testsuite/g++.dg/cpp0x/initlist-opt1.C
index 391b7c47d503..38c4f00cec0d 100644
--- a/gcc/testsuite/g++.dg/cpp0x/initlist-opt1.C
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist-opt1.C
@@ -1,5 +1,6 @@
 // PR c++/110102
 // { dg-do compile { target c++11 } }
+// { dg-additional-options "-fconcepts-diagnostics-depth=2" { target c++20 } }
 // { dg-skip-if "requires hosted libstdc++ for list" { ! hostedlib } }
 
 // { dg-error "deleted|construct_at" "" { target *-*-* } 0 }
diff --git a/libstdc++-v3/include/bits/stl_construct.h 
b/libstdc++-v3/include/bits/stl_construct.h
index dc08fb7ea33d..146ea14e99ad 100644
--- a/libstdc++-v3/include/bits/stl_construct.h
+++ b/libstdc++-v3/include/bits/stl_construct.h
@@ -90,11 +90,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 #if __cpp_constexpr_dynamic_alloc // >= C++20
   template
-constexpr auto
+requires (!is_unbounded_array_v<_Tp>)
+  && requires { ::new((void*)0) _Tp(std::declval<_Args>()...); }
+constexpr _Tp*
 construct_at(_Tp* __location, _Args&&... __args)
 noexcept(noexcept(::new((void*)0) _Tp(std::declval<_Args>()...)))
--> decltype(::new((void*)0) _Tp(std::declval<_Args>()...))
-{ return ::new((void*)__location) _Tp(std::forward<_Args>(__args)...); }
+{
+  void* __loc = const_cast*>(__location);
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // 3436. std::construct_at should support arrays
+  if constexpr (is_array_v<_Tp>)
+   {
+ static_assert(sizeof...(_Args) == 0, "std::construct_at for array "
+  "types must not use any arguments to initialize the "
+  "array");
+ return ::new(__loc) _Tp[1]();
+   }
+  else
+   return ::new(__loc) _Tp(std::forward<_Args>(__args)...);
+}
 #endif // C++20
 #endif// C++17
 
diff --git 
a/libstdc++-v3/testsuite/20_util/specialized_algorithms/construct_at/array.cc 
b/libstdc++-v3/testsuite/20_util/specialized_algorithms/construct_at/array.cc
new file mode 100644
index ..c36834628355
--- /dev/null
+++ 
b/libstdc++-v3/testsuite/20_util/specialized_algorithms/construct_at/array.cc
@@ -0,0 +1,41 @@
+// { dg-do compile { target c++20 } }
+
+// LWG 3436. std::construct_at should support arrays
+
+#include 
+#include 
+
+constexpr void
+test_array()
+{
+  int arr[1] { 99 };
+  std::construct_at(&arr);
+  VERIFY( arr[0] == 0 );
+
+  union U {
+long long x;
+int arr[4];
+  } u;
+  u.x = -1;
+
+  auto p = std::construct_at(&u.arr);
+  VERIFY( (*p)[0] == 0 );
+  VERIFY( (*p)[1] == 0 );
+  VERIFY( (*p)[2] == 0 );
+  VERIFY( (*p)[3] == 0 );
+
+  struct NonTrivial {
+constexpr NonTrivial() : i(99) { }
+int i;
+  };
+
+  union U2 {
+char c = 'a';
+NonTrivial arr[2];
+  } u2;
+
+  auto p2 = std::construct_at(&u2.arr);
+  VERIFY( (*p2)[0].i == 99 );
+}
+
+static_assert( [] { test_array(); return true; }() );
diff --git 
a/libstdc++-v3/testsuite/20_util/specialized_algorithms/construct_at/array_neg.cc
 
b/libstdc++-v3/testsuite/20_util/specialized_algorithms/construct_at/array_neg.cc
new file mode 100644
index ..deb86930d1a3
--- /dev/null
+++ 
b/libstdc++-v3/testsuite/20_util/specialized_algorithms/construct_at/array_neg.cc
@@ -0,0 +1,19 @@
+// { dg-do compile { target c++20 } }
+
+// LWG 3436. std::construct_at should support arrays
+
+#include 
+
+void
+test_array_args()
+{
+  int arr[2];
+  std::construct_at(&arr, 1, 2); // { dg-error "here" }
+  // { dg-error "must not use any arguments" "" { target *-*-* } 0 }
+}
+
+void
+test_unbounded_array(int (*p)[])
+{
+  std::construct_at(p); // { dg-error "no matching function" }
+}


[gcc r12-10756] libstdc++: Fix std::string_view for IL32P16 targets

2024-10-07 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:60e536d6f1682f3009c598db0f9c268db5d1749c

commit r12-10756-g60e536d6f1682f3009c598db0f9c268db5d1749c
Author: Jonathan Wakely 
Date:   Mon Nov 28 12:16:21 2022 +

libstdc++: Fix std::string_view for IL32P16 targets

For H8/300 with -msx -mn -mint32 the type of (_M_len - __pos) is int,
because int is wider than size_t so the operands are promoted.

libstdc++-v3/ChangeLog:

* include/std/string_view (basic_string_view::copy) Use explicit
template argument for call to std::min.
(basic_string_view::substr): Likewise.

Diff:
---
 libstdc++-v3/include/std/string_view | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/std/string_view 
b/libstdc++-v3/include/std/string_view
index 9ee888363813..23383f578e5e 100644
--- a/libstdc++-v3/include/std/string_view
+++ b/libstdc++-v3/include/std/string_view
@@ -299,7 +299,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   {
__glibcxx_requires_string_len(__str, __n);
__pos = std::__sv_check(size(), __pos, "basic_string_view::copy");
-   const size_type __rlen = std::min(__n, _M_len - __pos);
+   const size_type __rlen = std::min(__n, _M_len - __pos);
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2777. basic_string_view::copy should use char_traits::copy
traits_type::copy(__str, data() + __pos, __rlen);
@@ -310,7 +310,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   substr(size_type __pos = 0, size_type __n = npos) const noexcept(false)
   {
__pos = std::__sv_check(size(), __pos, "basic_string_view::substr");
-   const size_type __rlen = std::min(__n, _M_len - __pos);
+   const size_type __rlen = std::min(__n, _M_len - __pos);
return basic_string_view{_M_str + __pos, __rlen};
   }


[gcc r12-10753] libstdc++: Fix std::tr2::dynamic_bitset shift operations [PR115399]

2024-10-07 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:1f655ef43621cc022745c3aa9c77e3725b9280cd

commit r12-10753-g1f655ef43621cc022745c3aa9c77e3725b9280cd
Author: Jonathan Wakely 
Date:   Mon Jun 10 14:08:16 2024 +0100

libstdc++: Fix std::tr2::dynamic_bitset shift operations [PR115399]

The shift operations for dynamic_bitset fail to zero out words where the
non-zero bits were shifted to a completely different word.

For a right shift we don't need to sanitize the unused bits in the high
word, because we know they were already clear and a right shift doesn't
change that.

libstdc++-v3/ChangeLog:

PR libstdc++/115399
* include/tr2/dynamic_bitset (operator>>=): Remove redundant
call to _M_do_sanitize.
* include/tr2/dynamic_bitset.tcc (_M_do_left_shift): Zero out
low bits in words that should no longer be populated.
(_M_do_right_shift): Likewise for high bits.
* testsuite/tr2/dynamic_bitset/pr115399.cc: New test.

(cherry picked from commit bd3a312728fbf8c35a09239b9180269f938f872e)

Diff:
---
 libstdc++-v3/include/tr2/dynamic_bitset|  5 +--
 libstdc++-v3/include/tr2/dynamic_bitset.tcc|  6 ++--
 .../testsuite/tr2/dynamic_bitset/pr115399.cc   | 37 ++
 3 files changed, 40 insertions(+), 8 deletions(-)

diff --git a/libstdc++-v3/include/tr2/dynamic_bitset 
b/libstdc++-v3/include/tr2/dynamic_bitset
index 0d2160d611d2..3bed740624bd 100644
--- a/libstdc++-v3/include/tr2/dynamic_bitset
+++ b/libstdc++-v3/include/tr2/dynamic_bitset
@@ -815,10 +815,7 @@ namespace tr2
   operator>>=(size_type __pos)
   {
if (__builtin_expect(__pos < this->_M_Nb, 1))
- {
-   this->_M_do_right_shift(__pos);
-   this->_M_do_sanitize();
- }
+ this->_M_do_right_shift(__pos);
else
  this->_M_do_reset();
return *this;
diff --git a/libstdc++-v3/include/tr2/dynamic_bitset.tcc 
b/libstdc++-v3/include/tr2/dynamic_bitset.tcc
index 8392ba6ffe6b..41f4dc291200 100644
--- a/libstdc++-v3/include/tr2/dynamic_bitset.tcc
+++ b/libstdc++-v3/include/tr2/dynamic_bitset.tcc
@@ -60,8 +60,7 @@ namespace tr2
  this->_M_w[__wshift] = this->_M_w[0] << __offset;
}
 
-  std::fill(this->_M_w.begin(), this->_M_w.begin() + __wshift,
-   static_cast<_WordT>(0));
+ std::fill_n(this->_M_w.begin(), __wshift, _WordT(0));
}
 }
 
@@ -88,8 +87,7 @@ namespace tr2
  this->_M_w[__limit] = this->_M_w[_M_w.size()-1] >> __offset;
}
 
- std::fill(this->_M_w.begin() + __limit + 1, this->_M_w.end(),
-   static_cast<_WordT>(0));
+ std::fill_n(this->_M_w.end() - __wshift, __wshift, _WordT(0));
}
 }
 
diff --git a/libstdc++-v3/testsuite/tr2/dynamic_bitset/pr115399.cc 
b/libstdc++-v3/testsuite/tr2/dynamic_bitset/pr115399.cc
new file mode 100644
index ..e626e4a5d156
--- /dev/null
+++ b/libstdc++-v3/testsuite/tr2/dynamic_bitset/pr115399.cc
@@ -0,0 +1,37 @@
+// { dg-do run { target c++11 } }
+
+// PR libstdc++/115399
+// std::tr2::dynamic_bitset shift behaves differently from std::bitset
+
+#include 
+#include 
+
+void
+test_left_shift()
+{
+  std::tr2::dynamic_bitset<> b(65);
+  b[0] = 1;
+  auto b2 = b << 64;
+  VERIFY(b2[64] == 1);
+  VERIFY(b2[0] == 0);
+  b <<= 64;
+  VERIFY( b2 == b );
+}
+
+void
+test_right_shift()
+{
+  std::tr2::dynamic_bitset<> b(65);
+  b[64] = 1;
+  auto b2 = b >> 64;
+  VERIFY(b2[64] == 0);
+  VERIFY(b2[0] == 1);
+  b >>= 64;
+  VERIFY( b2 == b );
+}
+
+int main()
+{
+  test_left_shift();
+  test_right_shift();
+}


[gcc r12-10752] libstdc++: Fix @headername for bits/cpp_type_traits.h

2024-10-07 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:556051a7bf9373dc8a0f607b5d1ae177a2b5afad

commit r12-10752-g556051a7bf9373dc8a0f607b5d1ae177a2b5afad
Author: Kim Gräsman 
Date:   Tue Aug 27 17:08:47 2024 +0100

libstdc++: Fix @headername for bits/cpp_type_traits.h

There is no file ext/type_traits, point it to ext/type_traits.h instead.

libstdc++-v3/ChangeLog:

* include/bits/cpp_type_traits.h: Improve doxygen file docs.

(cherry picked from commit f6ed7a61a7c906f8fb7f8059132225c9bc41f3b2)

Diff:
---
 libstdc++-v3/include/bits/cpp_type_traits.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/bits/cpp_type_traits.h 
b/libstdc++-v3/include/bits/cpp_type_traits.h
index 8f91bbedbed0..550820100ccd 100644
--- a/libstdc++-v3/include/bits/cpp_type_traits.h
+++ b/libstdc++-v3/include/bits/cpp_type_traits.h
@@ -24,7 +24,7 @@
 
 /** @file bits/cpp_type_traits.h
  *  This is an internal header file, included by other library headers.
- *  Do not attempt to use it directly. @headername{ext/type_traits}
+ *  Do not attempt to use it directly. @headername{ext/type_traits.h}
  */
 
 // Written by Gabriel Dos Reis 


[gcc r12-10751] libstdc++: Fix @file for target-specific opt_random.h

2024-10-07 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:99a3f6587cf2fa2d50890f1ee8b28c4b0a23c7bc

commit r12-10751-g99a3f6587cf2fa2d50890f1ee8b28c4b0a23c7bc
Author: Kim Gräsman 
Date:   Tue Aug 27 17:11:29 2024 +0100

libstdc++: Fix @file for target-specific opt_random.h

A few of these files self-identified as ext/random.tcc, update to use
the actual basename.

libstdc++-v3/ChangeLog:

* config/cpu/aarch64/opt/ext/opt_random.h: Improve doxygen file
docs.
* config/cpu/i486/opt/ext/opt_random.h: Likewise.

(cherry picked from commit c2ad7b2d5247cf2ddee98d7f46274775a3fa1268)

Diff:
---
 libstdc++-v3/config/cpu/aarch64/opt/ext/opt_random.h | 2 +-
 libstdc++-v3/config/cpu/i486/opt/ext/opt_random.h| 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/config/cpu/aarch64/opt/ext/opt_random.h 
b/libstdc++-v3/config/cpu/aarch64/opt/ext/opt_random.h
index 1d5cf6e6f345..58c0d0347fbd 100644
--- a/libstdc++-v3/config/cpu/aarch64/opt/ext/opt_random.h
+++ b/libstdc++-v3/config/cpu/aarch64/opt/ext/opt_random.h
@@ -22,7 +22,7 @@
 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 // .
 
-/** @file ext/random.tcc
+/** @file ext/opt_random.h
  *  This is an internal header file, included by other library headers.
  *  Do not attempt to use it directly. @headername{ext/random}
  */
diff --git a/libstdc++-v3/config/cpu/i486/opt/ext/opt_random.h 
b/libstdc++-v3/config/cpu/i486/opt/ext/opt_random.h
index bf3bbcce6f74..36889427b0df 100644
--- a/libstdc++-v3/config/cpu/i486/opt/ext/opt_random.h
+++ b/libstdc++-v3/config/cpu/i486/opt/ext/opt_random.h
@@ -22,7 +22,7 @@
 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 // .
 
-/** @file ext/random.tcc
+/** @file ext/opt_random.h
  *  This is an internal header file, included by other library headers.
  *  Do not attempt to use it directly. @headername{ext/random}
  */


[gcc r12-10749] libstdc++: Fix autoconf check for O_NONBLOCK in

2024-10-07 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:f5ffdcfe3b58771b4482d94264cf076df83a2cdc

commit r12-10749-gf5ffdcfe3b58771b4482d94264cf076df83a2cdc
Author: Jonathan Wakely 
Date:   Wed Aug 28 12:38:18 2024 +0100

libstdc++: Fix autoconf check for O_NONBLOCK in 

I misused the AC_CHECK_DECL macro, assuming that it behaved like
AC_CHECK_DECLS and always defined a HAVE_xxx macro if the decl was
found. Instead, the [action-if-found] shell commands are needed to
defined HAVE_O_NONBLOCK explicitly.

libstdc++-v3/ChangeLog:

* configure.ac: Fix check for O_NONBLOCK.
* config.h.in: Regenerate.
* configure: Regenerate.

(cherry picked from commit b68561dd7925dfee1836f75d3fa8d33fff5c2498)

Diff:
---
 libstdc++-v3/config.h.in  | 3 +++
 libstdc++-v3/configure| 2 ++
 libstdc++-v3/configure.ac | 5 -
 3 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/config.h.in b/libstdc++-v3/config.h.in
index 639000d797ad..4bf9b4282280 100644
--- a/libstdc++-v3/config.h.in
+++ b/libstdc++-v3/config.h.in
@@ -295,6 +295,9 @@
 /* Define if openat is available in . */
 #undef HAVE_OPENAT
 
+/* Define if O_NONBLOCK is defined in  */
+#undef HAVE_O_NONBLOCK
+
 /* Define if poll is available in . */
 #undef HAVE_POLL
 
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index ccc23f1b3522..3ea275e9ab2c 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -77901,6 +77901,8 @@ if test 
"$ac_cv_have_decl_F_GETFL$ac_cv_have_decl_F_SETFL" = yesyes ; then
 "
 if test "x$ac_cv_have_decl_O_NONBLOCK" = xyes; then :
 
+$as_echo "#define HAVE_O_NONBLOCK 1" >>confdefs.h
+
 fi
 
 fi
diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac
index dc0c61973d1c..dad313a23767 100644
--- a/libstdc++-v3/configure.ac
+++ b/libstdc++-v3/configure.ac
@@ -503,7 +503,10 @@ AC_CHECK_HEADERS([fcntl.h sys/ioctl.h sys/socket.h 
sys/uio.h poll.h netdb.h arpa
 AC_CHECK_DECL(F_GETFL,,,[#include ])
 AC_CHECK_DECL(F_SETFL,,,[#include ])
 if test "$ac_cv_have_decl_F_GETFL$ac_cv_have_decl_F_SETFL" = yesyes ; then
-  AC_CHECK_DECL(O_NONBLOCK,,,[#include ])
+  AC_CHECK_DECL(O_NONBLOCK,
+AC_DEFINE(HAVE_O_NONBLOCK,1,[Define if O_NONBLOCK is defined in 
]),
+[],
+[#include ])
 fi
 
 # For Transactional Memory TS


[gcc r13-9081] libstdc++: Fix @headername for bits/cpp_type_traits.h

2024-10-04 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:995725189e5107c40f10b960549fab0a2b3bb976

commit r13-9081-g995725189e5107c40f10b960549fab0a2b3bb976
Author: Kim Gräsman 
Date:   Tue Aug 27 17:08:47 2024 +0100

libstdc++: Fix @headername for bits/cpp_type_traits.h

There is no file ext/type_traits, point it to ext/type_traits.h instead.

libstdc++-v3/ChangeLog:

* include/bits/cpp_type_traits.h: Improve doxygen file docs.

(cherry picked from commit f6ed7a61a7c906f8fb7f8059132225c9bc41f3b2)

Diff:
---
 libstdc++-v3/include/bits/cpp_type_traits.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/bits/cpp_type_traits.h 
b/libstdc++-v3/include/bits/cpp_type_traits.h
index 4312f32a4e07..e466ee9291bd 100644
--- a/libstdc++-v3/include/bits/cpp_type_traits.h
+++ b/libstdc++-v3/include/bits/cpp_type_traits.h
@@ -24,7 +24,7 @@
 
 /** @file bits/cpp_type_traits.h
  *  This is an internal header file, included by other library headers.
- *  Do not attempt to use it directly. @headername{ext/type_traits}
+ *  Do not attempt to use it directly. @headername{ext/type_traits.h}
  */
 
 // Written by Gabriel Dos Reis 


[gcc r13-9079] libstdc++: Use reserved form of [[__likely__]] in

2024-10-04 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:cd53e6a50567fe890b5c2266a3b318321fc19a55

commit r13-9079-gcd53e6a50567fe890b5c2266a3b318321fc19a55
Author: Jonathan Wakely 
Date:   Fri Jul 5 20:00:04 2024 +0100

libstdc++: Use reserved form of [[__likely__]] in 

We should not use [[unlikely]] before C++20, so use [[__unlikely__]]
instead.

libstdc++-v3/ChangeLog:

* include/std/variant (_Variant_storage::_M_reset): Use
__unlikely__ form of attribute instead of unlikely.

(cherry picked from commit 9f1cd51766f251aafe0f1b898892f79855892729)

Diff:
---
 libstdc++-v3/include/std/variant | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant
index a31b7e772388..1a34a2f2e7f5 100644
--- a/libstdc++-v3/include/std/variant
+++ b/libstdc++-v3/include/std/variant
@@ -490,7 +490,7 @@ namespace __variant
   constexpr void
   _M_reset()
   {
-   if (!_M_valid()) [[unlikely]]
+   if (!_M_valid()) [[__unlikely__]]
  return;
 
std::__do_visit([](auto&& __this_mem) mutable


[gcc r13-9080] libstdc++: Fix @file for target-specific opt_random.h

2024-10-04 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:2a30e7f9dc59ebcb8350959e94f61a9c68710f52

commit r13-9080-g2a30e7f9dc59ebcb8350959e94f61a9c68710f52
Author: Kim Gräsman 
Date:   Tue Aug 27 17:11:29 2024 +0100

libstdc++: Fix @file for target-specific opt_random.h

A few of these files self-identified as ext/random.tcc, update to use
the actual basename.

libstdc++-v3/ChangeLog:

* config/cpu/aarch64/opt/ext/opt_random.h: Improve doxygen file
docs.
* config/cpu/i486/opt/ext/opt_random.h: Likewise.

(cherry picked from commit c2ad7b2d5247cf2ddee98d7f46274775a3fa1268)

Diff:
---
 libstdc++-v3/config/cpu/aarch64/opt/ext/opt_random.h | 2 +-
 libstdc++-v3/config/cpu/i486/opt/ext/opt_random.h| 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/config/cpu/aarch64/opt/ext/opt_random.h 
b/libstdc++-v3/config/cpu/aarch64/opt/ext/opt_random.h
index 93981eb08f67..a1c05e8f7a79 100644
--- a/libstdc++-v3/config/cpu/aarch64/opt/ext/opt_random.h
+++ b/libstdc++-v3/config/cpu/aarch64/opt/ext/opt_random.h
@@ -22,7 +22,7 @@
 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 // .
 
-/** @file ext/random.tcc
+/** @file ext/opt_random.h
  *  This is an internal header file, included by other library headers.
  *  Do not attempt to use it directly. @headername{ext/random}
  */
diff --git a/libstdc++-v3/config/cpu/i486/opt/ext/opt_random.h 
b/libstdc++-v3/config/cpu/i486/opt/ext/opt_random.h
index 148d90e5023b..3a0f99bb9e0b 100644
--- a/libstdc++-v3/config/cpu/i486/opt/ext/opt_random.h
+++ b/libstdc++-v3/config/cpu/i486/opt/ext/opt_random.h
@@ -22,7 +22,7 @@
 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 // .
 
-/** @file ext/random.tcc
+/** @file ext/opt_random.h
  *  This is an internal header file, included by other library headers.
  *  Do not attempt to use it directly. @headername{ext/random}
  */


[gcc r14-10741] libstdc++: Fix @headername for bits/cpp_type_traits.h

2024-10-03 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:ab9ab537b11a6a82f283b08898b67f83f4a19e57

commit r14-10741-gab9ab537b11a6a82f283b08898b67f83f4a19e57
Author: Kim Gräsman 
Date:   Tue Aug 27 17:08:47 2024 +0100

libstdc++: Fix @headername for bits/cpp_type_traits.h

There is no file ext/type_traits, point it to ext/type_traits.h instead.

libstdc++-v3/ChangeLog:

* include/bits/cpp_type_traits.h: Improve doxygen file docs.

(cherry picked from commit f6ed7a61a7c906f8fb7f8059132225c9bc41f3b2)

Diff:
---
 libstdc++-v3/include/bits/cpp_type_traits.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/bits/cpp_type_traits.h 
b/libstdc++-v3/include/bits/cpp_type_traits.h
index 59f1a1875eb8..0cb482f54b41 100644
--- a/libstdc++-v3/include/bits/cpp_type_traits.h
+++ b/libstdc++-v3/include/bits/cpp_type_traits.h
@@ -24,7 +24,7 @@
 
 /** @file bits/cpp_type_traits.h
  *  This is an internal header file, included by other library headers.
- *  Do not attempt to use it directly. @headername{ext/type_traits}
+ *  Do not attempt to use it directly. @headername{ext/type_traits.h}
  */
 
 // Written by Gabriel Dos Reis 


[gcc r14-10739] libstdc++: Fix autoconf check for O_NONBLOCK in

2024-10-03 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:1982bd34cf63beef4d86a048bc16aab11a1ad71b

commit r14-10739-g1982bd34cf63beef4d86a048bc16aab11a1ad71b
Author: Jonathan Wakely 
Date:   Wed Aug 28 12:38:18 2024 +0100

libstdc++: Fix autoconf check for O_NONBLOCK in 

I misused the AC_CHECK_DECL macro, assuming that it behaved like
AC_CHECK_DECLS and always defined a HAVE_xxx macro if the decl was
found. Instead, the [action-if-found] shell commands are needed to
defined HAVE_O_NONBLOCK explicitly.

libstdc++-v3/ChangeLog:

* configure.ac: Fix check for O_NONBLOCK.
* config.h.in: Regenerate.
* configure: Regenerate.

(cherry picked from commit b68561dd7925dfee1836f75d3fa8d33fff5c2498)

Diff:
---
 libstdc++-v3/config.h.in  | 3 +++
 libstdc++-v3/configure| 2 ++
 libstdc++-v3/configure.ac | 5 -
 3 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/config.h.in b/libstdc++-v3/config.h.in
index 906e0143099e..9cba3d9c8ee4 100644
--- a/libstdc++-v3/config.h.in
+++ b/libstdc++-v3/config.h.in
@@ -302,6 +302,9 @@
 /* Define if openat is available in . */
 #undef HAVE_OPENAT
 
+/* Define if O_NONBLOCK is defined in  */
+#undef HAVE_O_NONBLOCK
+
 /* Define if poll is available in . */
 #undef HAVE_POLL
 
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index 21abaeb07788..18053ab7eae6 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -54085,6 +54085,8 @@ if test 
"$ac_cv_have_decl_F_GETFL$ac_cv_have_decl_F_SETFL" = yesyes ; then
 "
 if test "x$ac_cv_have_decl_O_NONBLOCK" = xyes; then :
 
+$as_echo "#define HAVE_O_NONBLOCK 1" >>confdefs.h
+
 fi
 
 fi
diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac
index 37396bd6ebbe..a6525a9d3e46 100644
--- a/libstdc++-v3/configure.ac
+++ b/libstdc++-v3/configure.ac
@@ -539,7 +539,10 @@ AC_CHECK_HEADERS([fcntl.h sys/ioctl.h sys/socket.h 
sys/uio.h poll.h netdb.h arpa
 AC_CHECK_DECL(F_GETFL,,,[#include ])
 AC_CHECK_DECL(F_SETFL,,,[#include ])
 if test "$ac_cv_have_decl_F_GETFL$ac_cv_have_decl_F_SETFL" = yesyes ; then
-  AC_CHECK_DECL(O_NONBLOCK,,,[#include ])
+  AC_CHECK_DECL(O_NONBLOCK,
+AC_DEFINE(HAVE_O_NONBLOCK,1,[Define if O_NONBLOCK is defined in 
]),
+[],
+[#include ])
 fi
 
 # For Transactional Memory TS


[gcc r14-10742] libstdc++: Make debug sequence members mutable [PR116369]

2024-10-03 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:4ef6b95d5dabba0a907d9545f901c77f0a5cb42d

commit r14-10742-g4ef6b95d5dabba0a907d9545f901c77f0a5cb42d
Author: Jonathan Wakely 
Date:   Wed Aug 21 12:29:32 2024 +0100

libstdc++: Make debug sequence members mutable [PR116369]

We need to be able to attach debug mode iterators to const containers,
so the safe iterator constructor uses const_cast to get a modifiable
pointer to the container. If the container was defined as const, that
const_cast to access its members results in undefined behaviour.  PR
116369 shows a case where it results in a segfault because the container
is in a rodata section (which shouldn't have happened, but the undefined
behaviour in the library still exists in any case).

This makes the _M_iterators and _M_const_iterators data members mutable,
so that it's safe to modify them even if the declared type of the
container is a const type.

Ideally we would not need the const_cast at all. Instead, the _M_attach
member (and everything it calls) should be const-qualified. That would
work fine now, because the members that it ends up modifying are
mutable. Making that change would require a number of new exports from
the shared library, and would require retaining the old non-const member
functions (maybe as symbol aliases) for backwards compatibility. That
might be worth changing at some point, but isn't done here.

libstdc++-v3/ChangeLog:

PR c++/116369
* include/debug/safe_base.h (_Safe_sequence_base::_M_iterators):
Add mutable specifier.
(_Safe_sequence_base::_M_const_iterators): Likewise.

(cherry picked from commit a35dd276cbf6236e08bcf6e56e62c2be41cf6e3c)

Diff:
---
 libstdc++-v3/include/debug/safe_base.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/debug/safe_base.h 
b/libstdc++-v3/include/debug/safe_base.h
index d5fbe4b1320b..88d7f0b05c8b 100644
--- a/libstdc++-v3/include/debug/safe_base.h
+++ b/libstdc++-v3/include/debug/safe_base.h
@@ -205,10 +205,10 @@ namespace __gnu_debug
 
   public:
 /// The list of mutable iterators that reference this container
-_Safe_iterator_base* _M_iterators;
+mutable _Safe_iterator_base* _M_iterators;
 
 /// The list of constant iterators that reference this container
-_Safe_iterator_base* _M_const_iterators;
+mutable _Safe_iterator_base* _M_const_iterators;
 
 /// The container version number. This number may never be 0.
 mutable unsigned int _M_version;


[gcc r14-10737] libstdc++: Fix std::codecvt for empty dest [PR37475]

2024-10-03 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:c4253d6a170f40725ce3a11ce7a3e236b6e4842f

commit r14-10737-gc4253d6a170f40725ce3a11ce7a3e236b6e4842f
Author: Jonathan Wakely 
Date:   Tue Jun 11 16:45:43 2024 +0100

libstdc++: Fix std::codecvt for empty dest 
[PR37475]

For the GNU locale model, codecvt::do_out and codecvt::do_in incorrectly
return 'ok' when the destination range is empty. That happens because
detecting incomplete output is done in the loop body, and the loop is
never even entered if to == to_end.

By restructuring the loop condition so that we check the output range
separately, we can ensure that for a non-empty source range, we always
enter the loop at least once, and detect if the destination range is too
small.

The loops also seem easier to reason about if we return immediately on
any error, instead of checking the result twice on every iteration. We
can use an RAII type to restore the locale before returning, which also
simplifies all the other member functions.

libstdc++-v3/ChangeLog:

PR libstdc++/37475
* config/locale/gnu/codecvt_members.cc (Guard): New RAII type.
(do_out, do_in): Return partial if the destination is empty but
the source is not. Use Guard to restore locale on scope exit.
Return immediately on any conversion error.
(do_encoding, do_max_length, do_length): Use Guard.
* testsuite/22_locale/codecvt/in/char/37475.cc: New test.
* testsuite/22_locale/codecvt/in/wchar_t/37475.cc: New test.
* testsuite/22_locale/codecvt/out/char/37475.cc: New test.
* testsuite/22_locale/codecvt/out/wchar_t/37475.cc: New test.

(cherry picked from commit 73ad57c244c283bf6da0c16630212f11b945eda5)

Diff:
---
 libstdc++-v3/config/locale/gnu/codecvt_members.cc  | 117 +
 .../testsuite/22_locale/codecvt/in/char/37475.cc   |  23 
 .../22_locale/codecvt/in/wchar_t/37475.cc  |  23 
 .../testsuite/22_locale/codecvt/out/char/37475.cc  |  23 
 .../22_locale/codecvt/out/wchar_t/37475.cc |  23 
 5 files changed, 142 insertions(+), 67 deletions(-)

diff --git a/libstdc++-v3/config/locale/gnu/codecvt_members.cc 
b/libstdc++-v3/config/locale/gnu/codecvt_members.cc
index 034713d236ef..794f25a5f356 100644
--- a/libstdc++-v3/config/locale/gnu/codecvt_members.cc
+++ b/libstdc++-v3/config/locale/gnu/codecvt_members.cc
@@ -37,8 +37,23 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-  // Specializations.
 #ifdef _GLIBCXX_USE_WCHAR_T
+namespace
+{
+  // RAII type for changing and restoring the current thread's locale.
+  struct Guard
+  {
+#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
+explicit Guard(__c_locale loc) : old(__uselocale(loc)) { }
+~Guard() { __uselocale(old); }
+#else
+explicit Guard(__c_locale) { }
+#endif
+__c_locale old;
+  };
+}
+
+  // Specializations.
   codecvt_base::result
   codecvt::
   do_out(state_type& __state, const intern_type* __from,
@@ -46,22 +61,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 extern_type* __to, extern_type* __to_end,
 extern_type*& __to_next) const
   {
-result __ret = ok;
 state_type __tmp_state(__state);
-
-#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
-__c_locale __old = __uselocale(_M_c_locale_codecvt);
-#endif
+Guard g(_M_c_locale_codecvt);
 
 // wcsnrtombs is *very* fast but stops if encounters NUL characters:
 // in case we fall back to wcrtomb and then continue, in a loop.
 // NB: wcsnrtombs is a GNU extension
-for (__from_next = __from, __to_next = __to;
-__from_next < __from_end && __to_next < __to_end
-&& __ret == ok;)
+__from_next = __from;
+__to_next = __to;
+while (__from_next < __from_end)
   {
-   const intern_type* __from_chunk_end = wmemchr(__from_next, L'\0',
- __from_end - __from_next);
+   if (__to_next >= __to_end)
+ return partial;
+
+   const intern_type* __from_chunk_end
+ = wmemchr(__from_next, L'\0', __from_end - __from_next);
if (!__from_chunk_end)
  __from_chunk_end = __from_end;
 
@@ -77,12 +91,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
for (; __from < __from_next; ++__from)
  __to_next += wcrtomb(__to_next, *__from, &__tmp_state);
__state = __tmp_state;
-   __ret = error;
+   return error;
  }
else if (__from_next && __from_next < __from_chunk_end)
  {
__to_next += __conv;
-   __ret = partial;
+   return partial;
  }
else
  {
@@ -90,13 +104,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__to_next += __conv;
  }
 
-   if (__from_next < __from_end && __ret == ok)
+   if (__from_next < __from_end)
  {
exte

[gcc r14-10736] libstdc++: Populate std::time_get::get's %c format for C locale

2024-10-03 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:c5bdd24abac34382c6d503c1265649f65e750b54

commit r14-10736-gc5bdd24abac34382c6d503c1265649f65e750b54
Author: Jonathan Wakely 
Date:   Tue Sep 24 23:20:56 2024 +0100

libstdc++: Populate std::time_get::get's %c format for C locale

We were using the empty string "" for D_T_FMT and ERA_D_T_FMT in the C
locale, instead of "%a %b %e %T %Y" as the C standard requires. Set it
correctly for each locale implementation that defines time_members.cc.

We can also explicitly set the _M_era_xxx pointers to the same values as
the corresponding _M_xxx ones, rather than setting them to point to
identical string literals. This doesn't rely on the compiler merging
string literals, and makes it more explicit that they're the same in the
C locale.

libstdc++-v3/ChangeLog:

* config/locale/dragonfly/time_members.cc
(__timepunct::_M_initialize_timepunc)
(__timepunct::_M_initialize_timepunc): Set
_M_date_time_format for C locale. Set %Ex formats to the same
values as the %x formats.
* config/locale/generic/time_members.cc: Likewise.
* config/locale/gnu/time_members.cc: Likewise.
* testsuite/22_locale/time_get/get/char/5.cc: New test.
* testsuite/22_locale/time_get/get/wchar_t/5.cc: New test.

(cherry picked from commit c534e37faccf481afa9bc28f0605ca0ec3846c89)

Diff:
---
 .../config/locale/dragonfly/time_members.cc| 16 +-
 libstdc++-v3/config/locale/generic/time_members.cc |  8 ++---
 libstdc++-v3/config/locale/gnu/time_members.cc | 16 +-
 .../testsuite/22_locale/time_get/get/char/5.cc | 37 ++
 .../testsuite/22_locale/time_get/get/wchar_t/5.cc  | 37 ++
 5 files changed, 94 insertions(+), 20 deletions(-)

diff --git a/libstdc++-v3/config/locale/dragonfly/time_members.cc 
b/libstdc++-v3/config/locale/dragonfly/time_members.cc
index 0c96928135eb..069b2ddd26bb 100644
--- a/libstdc++-v3/config/locale/dragonfly/time_members.cc
+++ b/libstdc++-v3/config/locale/dragonfly/time_members.cc
@@ -67,11 +67,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  _M_c_locale_timepunct = _S_get_c_locale();
 
  _M_data->_M_date_format = "%m/%d/%y";
- _M_data->_M_date_era_format = "%m/%d/%y";
+ _M_data->_M_date_era_format = _M_data->_M_date_format;
  _M_data->_M_time_format = "%H:%M:%S";
- _M_data->_M_time_era_format = "%H:%M:%S";
- _M_data->_M_date_time_format = "";
- _M_data->_M_date_time_era_format = "";
+ _M_data->_M_time_era_format = _M_data->_M_time_format;
+ _M_data->_M_date_time_format = "%a %b %e %T %Y";
+ _M_data->_M_date_time_era_format = _M_data->_M_date_time_format;
  _M_data->_M_am = "AM";
  _M_data->_M_pm = "PM";
  _M_data->_M_am_pm_format = "%I:%M:%S %p";
@@ -224,11 +224,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  _M_c_locale_timepunct = _S_get_c_locale();
 
  _M_data->_M_date_format = L"%m/%d/%y";
- _M_data->_M_date_era_format = L"%m/%d/%y";
+ _M_data->_M_date_era_format = _M_data->_M_date_format;
  _M_data->_M_time_format = L"%H:%M:%S";
- _M_data->_M_time_era_format = L"%H:%M:%S";
- _M_data->_M_date_time_format = L"";
- _M_data->_M_date_time_era_format = L"";
+ _M_data->_M_time_era_format = _M_data->_M_time_format;
+ _M_data->_M_date_time_format = L"%a %b %e %T %Y";
+ _M_data->_M_date_time_era_format = _M_data->_M_date_time_format;
  _M_data->_M_am = L"AM";
  _M_data->_M_pm = L"PM";
  _M_data->_M_am_pm_format = L"%I:%M:%S %p";
diff --git a/libstdc++-v3/config/locale/generic/time_members.cc 
b/libstdc++-v3/config/locale/generic/time_members.cc
index 68395820fefa..6619f0ca881a 100644
--- a/libstdc++-v3/config/locale/generic/time_members.cc
+++ b/libstdc++-v3/config/locale/generic/time_members.cc
@@ -65,11 +65,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_data = new __timepunct_cache;
 
   _M_data->_M_date_format = "%m/%d/%y";
-  _M_data->_M_date_era_format = "%m/%d/%y";
+  _M_data->_M_date_era_format = _M_data->_M_date_format;
   _M_data->_M_time_format = "%H:%M:%S";
-  _M_data->_M_time_era_format = "%H:%M:%S";
-  _M_data->_M_date_time_format = "";
-  _M_data->_M_date_time_era_format = "";
+  _M_data->_M_time_era_format = _M_data->_M_time_format;
+  _M_data->_M_date_time_format = "%a %b %e %T %Y";
+  _M_data->_M_date_time_era_format = _M_data->_M_date_time_format;
   _M_data->_M_am = "AM";
   _M_data->_M_pm = "PM";
   _M_data->_M_am_pm_format = "%I:%M:%S %p";
diff --git a/libstdc++-v3/config/locale/gnu/time_members.cc 
b/libstdc++-v3/config/locale/gnu/time_members.cc
index 1e3b87488fae..88c8ab700809 100644
--- a/libstdc++-v3/config/locale/gnu/time_members.cc
+++ b/libstdc++-v3/config/locale/gnu/time_members.cc
@@ 

[gcc r14-10733] libstdc++: Disable std::formatter specialization

2024-10-03 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:98ae5227a3e475e2c7d54d01fb5ee06cf0885ccc

commit r14-10733-g98ae5227a3e475e2c7d54d01fb5ee06cf0885ccc
Author: Jonathan Wakely 
Date:   Fri Sep 20 17:26:35 2024 +0100

libstdc++: Disable std::formatter specialization

I noticed that char8_t was missing from the list of types that were
prevented from using the std::formatter partial specialization for
integer types. That partial specialization was also matching
cv-qualified integer types, because std::integral is true.

This change simplifies the constraints by introducing a new variable
template which is only true for cv-unqualified integer types, with
explicit specializations to exclude the character types. This should be
slightly more efficient than the previous constraints that checked
std::integral and (!__is_one_of). It also
avoids the need for a separate std::formatter specialization for 128-bit
integers, as they can be handled by the new variable template too.

libstdc++-v3/ChangeLog:

* include/std/format (__format::__is_formattable_integer): New
variable template and specializations.
(template struct formatter): Replace
constraints on first arg with __is_formattable_integer.
* testsuite/std/format/formatter/requirements.cc: Check that
std::formatter specializations for char8_t and const int are
disabled.

(cherry picked from commit 0f52a92ab249bde64b7570d4cf549437a3283520)

Diff:
---
 libstdc++-v3/include/std/format| 53 --
 .../testsuite/std/format/formatter/requirements.cc | 17 +++
 2 files changed, 45 insertions(+), 25 deletions(-)

diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index 8f6a82a1fd41..95c2991765c3 100644
--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -1394,8 +1394,9 @@ namespace __format
 
   // We can format a floating-point type iff it is usable with to_chars.
   template
-concept __formattable_float = requires (_Tp __t, char* __p)
-{ __format::to_chars(__p, __p, __t, chars_format::scientific, 6); };
+concept __formattable_float
+  = is_same_v, _Tp> && requires (_Tp __t, char* __p)
+  { __format::to_chars(__p, __p, __t, chars_format::scientific, 6); };
 
   template<__char _CharT>
 struct __formatter_fp
@@ -2103,32 +2104,33 @@ namespace __format
 #endif // USE_WCHAR_T
   /// @}
 
-  /// Format an integer.
-  template
-requires (!__is_one_of<_Tp, char, wchar_t, char16_t, char32_t>::value)
-struct formatter<_Tp, _CharT>
-{
-  formatter() = default;
-
-  [[__gnu__::__always_inline__]]
-  constexpr typename basic_format_parse_context<_CharT>::iterator
-  parse(basic_format_parse_context<_CharT>& __pc)
-  {
-   return _M_f.template _M_parse<_Tp>(__pc);
-  }
+/// @cond undocumented
+namespace __format
+{
+  // each cv-unqualified arithmetic type ArithmeticT other than
+  // char, wchar_t, char8_t, char16_t, or char32_t
+  template
+constexpr bool __is_formattable_integer = __is_integer<_Tp>::__value;
 
-  template
-   typename basic_format_context<_Out, _CharT>::iterator
-   format(_Tp __u, basic_format_context<_Out, _CharT>& __fc) const
-   { return _M_f.format(__u, __fc); }
+#if defined __SIZEOF_INT128__
+  template<> inline constexpr bool __is_formattable_integer<__int128>  = true;
+  template<> inline constexpr bool __is_formattable_integer
+  = true;
+#endif
 
-private:
-  __format::__formatter_int<_CharT> _M_f;
-};
+  template<> inline constexpr bool __is_formattable_integer = false;
+  template<> inline constexpr bool __is_formattable_integer = false;
+#ifdef _GLIBCXX_USE_CHAR8_T
+  template<> inline constexpr bool __is_formattable_integer = false;
+#endif
+  template<> inline constexpr bool __is_formattable_integer = false;
+  template<> inline constexpr bool __is_formattable_integer = false;
+}
+/// ~endcond
 
-#if defined __SIZEOF_INT128__ && defined __STRICT_ANSI__
+  /// Format an integer.
   template
-requires (__is_one_of<_Tp, __int128, unsigned __int128>::value)
+requires __format::__is_formattable_integer<_Tp>
 struct formatter<_Tp, _CharT>
 {
   formatter() = default;
@@ -2148,7 +2150,6 @@ namespace __format
 private:
   __format::__formatter_int<_CharT> _M_f;
 };
-#endif
 
 #if defined __glibcxx_to_chars
   /// Format a floating-point value.
@@ -2541,6 +2542,8 @@ namespace __format
 } // namespace __format
 /// @endcond
 
+// Concept std::formattable was introduced by P2286R8 "Formatting Ranges",
+// but we can't guard it with __cpp_lib_format_ranges until we define that!
 #if __cplusplus > 202002L
   // [format.formattable], concept formattable
   template
diff --git a/libstdc++-v3/testsuite/std/format/formatter/requirements.cc 
b/libstdc++-v3/testsuite/std/format/formatter/requirements.cc
index bde67e586

[gcc r15-4039] libstdc++: Fix some warnings seen during bootstrap

2024-10-03 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:28911f626864e73c579ea2ad5f5308d2e8c3fcd9

commit r15-4039-g28911f626864e73c579ea2ad5f5308d2e8c3fcd9
Author: Jonathan Wakely 
Date:   Wed Oct 2 20:27:55 2024 +0100

libstdc++: Fix some warnings seen during bootstrap

libstdc++-v3/ChangeLog:

* include/bits/locale_facets_nonio.tcc (money_put::__do_get):
Ignore -Wformat warning for __ibm128 arguments.
* include/tr1/tuple (ignore): Ignore -Wunused warning.

Diff:
---
 libstdc++-v3/include/bits/locale_facets_nonio.tcc | 3 +++
 libstdc++-v3/include/tr1/tuple| 2 +-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/bits/locale_facets_nonio.tcc 
b/libstdc++-v3/include/bits/locale_facets_nonio.tcc
index 5fddc1e3b269..53553d113b23 100644
--- a/libstdc++-v3/include/bits/locale_facets_nonio.tcc
+++ b/libstdc++-v3/include/bits/locale_facets_nonio.tcc
@@ -637,6 +637,8 @@ _GLIBCXX_BEGIN_NAMESPACE_LDBL_OR_CXX11
 
 #if defined _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT \
   && defined __LONG_DOUBLE_IEEE128__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat" // '%Lf' expects 'long double'
 extern "C"
 __typeof__(__builtin_snprintf) __glibcxx_snprintfibm128 __asm__("snprintf");
 
@@ -671,6 +673,7 @@ __typeof__(__builtin_snprintf) __glibcxx_snprintfibm128 
__asm__("snprintf");
   return __intl ? _M_insert(__s, __io, __fill, __digits)
: _M_insert(__s, __io, __fill, __digits);
 }
+#pragma GCC diagnostic pop
 #endif
 
 _GLIBCXX_END_NAMESPACE_LDBL_OR_CXX11
diff --git a/libstdc++-v3/include/tr1/tuple b/libstdc++-v3/include/tr1/tuple
index b5c62b585a9a..f66090d36317 100644
--- a/libstdc++-v3/include/tr1/tuple
+++ b/libstdc++-v3/include/tr1/tuple
@@ -423,7 +423,7 @@ namespace tr1
   // TODO: Put this in some kind of shared file.
   namespace
   {
-_Swallow_assign ignore;
+_Swallow_assign ignore  __attribute__((__unused__));
   } // anonymous namespace
 }


[gcc r15-4015] libstdc++: Fix rounding in chrono::parse

2024-10-02 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:5cf26f2569bf007a2c9c058e43ddfe9a5f67da42

commit r15-4015-g5cf26f2569bf007a2c9c058e43ddfe9a5f67da42
Author: Jonathan Wakely 
Date:   Fri Sep 6 21:41:47 2024 +0100

libstdc++: Fix rounding in chrono::parse

I noticed that chrono::parse was using duration_cast and time_point_cast
to convert the parsed value to the result. Those functions truncate
towards zero, which is not generally what you want. Especially for
negative times before the epoch, where truncating towards zero rounds
"up" towards the next duration/time_point. Using chrono::round is
typically better, as that rounds to nearest.

However, while testing the fix I realised that rounding to the nearest
can give surprising results in some cases. For example if we parse a
chrono::sys_days using chrono::parse("F %T", "2024-09-22 18:34:56", tp)
then we will round up to the next day, i.e. sys_days(2024y/09/23). That
seems surprising, and I think 2024-09-22 is what most users would
expect.

This change attempts to provide a hybrid rounding heuristic where we use
chrono::round for the general case, but when the result has a period
that is one of minutes, hours, days, weeks, or years then we truncate
towards negative infinity using chrono::floor. This means that we
truncate "2024-09-22 18:34:56" to the start of the current
minute/hour/day/week/year, instead of rounding up to 2024-09-23, or to
18:35, or 17:00. For a period of months chrono::round is used, because
the months duration is defined as a twelfth of a year, which is not
actually the length of any calendar month. We don't want to truncate to
a whole number of "months" if that can actually go from e.g. 2023-03-01
to 2023-01-31, because February is shorter than chrono::months(1).

libstdc++-v3/ChangeLog:

* include/bits/chrono_io.h (__detail::__use_floor): New
function.
(__detail::__round): New function.
(from_stream): Use __detail::__round.
* testsuite/std/time/clock/file/io.cc: Check for expected
rounding in parse.
* testsuite/std/time/clock/gps/io.cc: Likewise.

Diff:
---
 libstdc++-v3/include/bits/chrono_io.h| 64 +---
 libstdc++-v3/testsuite/std/time/clock/file/io.cc | 21 +++-
 libstdc++-v3/testsuite/std/time/clock/gps/io.cc  | 20 
 3 files changed, 97 insertions(+), 8 deletions(-)

diff --git a/libstdc++-v3/include/bits/chrono_io.h 
b/libstdc++-v3/include/bits/chrono_io.h
index 1e34c82b532d..362bb5aa9e98 100644
--- a/libstdc++-v3/include/bits/chrono_io.h
+++ b/libstdc++-v3/include/bits/chrono_io.h
@@ -2407,6 +2407,56 @@ namespace __detail
   template
 using _Parser_t = _Parser>;
 
+  template
+consteval bool
+__use_floor()
+{
+  if constexpr (_Duration::period::den == 1)
+   {
+ switch (_Duration::period::num)
+ {
+   case minutes::period::num:
+   case hours::period::num:
+   case days::period::num:
+   case weeks::period::num:
+   case years::period::num:
+ return true;
+ }
+   }
+  return false;
+}
+
+  // A "do the right thing" rounding function for duration and time_point
+  // values extracted by from_stream. When treat_as_floating_point is true
+  // we don't want to do anything, just a straightforward conversion.
+  // When the destination type has a period of minutes, hours, days, weeks,
+  // or years, we use chrono::floor to truncate towards negative infinity.
+  // This ensures that an extracted timestamp such as 2024-09-05 13:00:00
+  // will produce 2024-09-05 when rounded to days, rather than rounding up
+  // to 2024-09-06 (a different day).
+  // Otherwise, use chrono::round to get the nearest value representable
+  // in the destination type.
+  template
+constexpr auto
+__round(const _Tp& __t)
+{
+  if constexpr (__is_duration_v<_Tp>)
+   {
+ if constexpr (treat_as_floating_point_v)
+   return chrono::duration_cast<_ToDur>(__t);
+ else if constexpr (__detail::__use_floor<_ToDur>())
+   return chrono::floor<_ToDur>(__t);
+ else
+   return chrono::round<_ToDur>(__t);
+   }
+  else
+   {
+ static_assert(__is_time_point_v<_Tp>);
+ using _Tpt = time_point;
+ return _Tpt(__detail::__round<_ToDur>(__t.time_since_epoch()));
+   }
+}
+
 } // namespace __detail
 /// @endcond
 
@@ -2421,7 +2471,7 @@ namespace __detail
   auto __need = __format::_ChronoParts::_TimeOfDay;
   __detail::_Parser_t> __p(__need);
   if (__p(__is, __fmt, __abbrev, __offset))
-   __d = chrono::duration_cast>(__p._M_time);
+   __d = __detail::__round>(__p._M_time);
   return __is;
 }
 
@@ -2882,7 +2932,7 @@ namespace __detail
  else
{
  auto __st = __p._M_sys_days + __p._M

[gcc r15-3932] libstdc++: Fix test FAILs due to -Wreturn-local-addr

2024-09-27 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:c580b8a2b59208efc687e2b706e3a40225167854

commit r15-3932-gc580b8a2b59208efc687e2b706e3a40225167854
Author: Jonathan Wakely 
Date:   Thu Sep 26 23:43:20 2024 +0100

libstdc++: Fix test FAILs due to -Wreturn-local-addr

This fixes two FAILs due to -Wpointer-arith warnings when testing with
c++11 or c++14 dialects.

libstdc++-v3/ChangeLog:

* testsuite/20_util/bind/dangling_ref.cc: Add an additional
dg-warning for -Wreturn-local-addr warning.
* testsuite/30_threads/packaged_task/cons/dangling_ref.cc:
Likewise.

Diff:
---
 libstdc++-v3/testsuite/20_util/bind/dangling_ref.cc  | 1 +
 libstdc++-v3/testsuite/30_threads/packaged_task/cons/dangling_ref.cc | 1 +
 2 files changed, 2 insertions(+)

diff --git a/libstdc++-v3/testsuite/20_util/bind/dangling_ref.cc 
b/libstdc++-v3/testsuite/20_util/bind/dangling_ref.cc
index 70393e4392f8..17e7b21c45cb 100644
--- a/libstdc++-v3/testsuite/20_util/bind/dangling_ref.cc
+++ b/libstdc++-v3/testsuite/20_util/bind/dangling_ref.cc
@@ -5,5 +5,6 @@ int f();
 auto b = std::bind(f);
 int i = b(); // { dg-error "here" "" { target { c++14_down } } }
 // { dg-error "dangling reference" "" { target { c++14_down } } 0 }
+// { dg-error "reference to temporary" "" { target { c++14_down } } 0 }
 // { dg-error "no matching function" "" { target c++17 } 0 }
 // { dg-error "enable_if" "" { target c++17 } 0 }
diff --git 
a/libstdc++-v3/testsuite/30_threads/packaged_task/cons/dangling_ref.cc 
b/libstdc++-v3/testsuite/30_threads/packaged_task/cons/dangling_ref.cc
index e9edb5edc8be..225b65fe6a7d 100644
--- a/libstdc++-v3/testsuite/30_threads/packaged_task/cons/dangling_ref.cc
+++ b/libstdc++-v3/testsuite/30_threads/packaged_task/cons/dangling_ref.cc
@@ -7,5 +7,6 @@
 int f();
 std::packaged_task task(f);
 // { dg-error "dangling reference" "" { target { c++14_down } } 0 }
+// { dg-error "reference to temporary" "" { target { c++14_down } } 0 }
 // { dg-error "no matching function" "" { target c++17 } 0 }
 // { dg-error "enable_if" "" { target c++17 } 0 }


[gcc r15-3901] libstdc++: Add [[nodiscard]] to iostream members

2024-09-26 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:240285eb307d289d56977f5300bcf0a1253af854

commit r15-3901-g240285eb307d289d56977f5300bcf0a1253af854
Author: Jonathan Wakely 
Date:   Thu Sep 26 12:14:54 2024 +0100

libstdc++: Add [[nodiscard]] to iostream members

These are all pure functions and MSVC also marks all of these as
nodiscard except for std::basic_ios::tie() const, but that's been
confirmed as an accidental omission.

libstdc++-v3/ChangeLog:

* include/bits/basic_ios.h (basic_ios::operator bool()):
Add [[nodiscard]] attribute.
(basic_ios::operator!(), basic_ios::rdstate())
(basic_ios::good(), basic_ios::eof(), basic_ios::fail())
(basic_ios::bad(), basic_ios::exceptions(), basic_ios::tie())
(basic_ios::rdbuf(), basic_ios::fill()): Likewise.
* include/bits/ios_base.h (ios_base::flags()): Likewise.
(ios_base::precision(), ios_base::width(), ios_base::getloc()):
Likewise.
* include/std/fstream (basic_filebuf::is_open)
(basic_ifstream::rdbuf(), basic_ifstream::is_open)
(basic_ofstream::rdbuf(), basic_ofstream::is_open)
(basic_fstream::rdbuf(), basic_fstream::is_open): Likewise.
* include/std/spanstream (basic_spanbuf::span())
(basic_ispanstream::span(), basic_ispanstream::rdbuf())
(basic_ospanstream::span(), basic_ospanstream::rdbuf())
(basic_spanstream::span(), basic_spanstream::rdbuf()):
Likewise.
* include/std/sstream (basic_stringbuf::str())
(basic_istringstream::rdbuf(), basic_istringstream::str())
(basic_ostringstream::rdbuf(), basic_ostringstream::str())
(basic_stringstream::rdbuf(), basic_stringstream::str()):
Likewise.
* testsuite/27_io/basic_istream/extractors_arithmetic/char/01.cc:
Suppress -Wunused-result warnings.
* testsuite/27_io/basic_istream/extractors_arithmetic/wchar_t/01.cc:
Likewise.

Diff:
---
 libstdc++-v3/include/bits/basic_ios.h | 11 +++
 libstdc++-v3/include/bits/ios_base.h  |  4 
 libstdc++-v3/include/std/fstream  | 10 ++
 libstdc++-v3/include/std/spanstream   |  7 +++
 libstdc++-v3/include/std/sstream  | 15 +++
 .../27_io/basic_istream/extractors_arithmetic/char/01.cc  |  4 ++--
 .../basic_istream/extractors_arithmetic/wchar_t/01.cc |  4 ++--
 7 files changed, 51 insertions(+), 4 deletions(-)

diff --git a/libstdc++-v3/include/bits/basic_ios.h 
b/libstdc++-v3/include/bits/basic_ios.h
index a2d8060edd22..8954ad16d63b 100644
--- a/libstdc++-v3/include/bits/basic_ios.h
+++ b/libstdc++-v3/include/bits/basic_ios.h
@@ -120,6 +120,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  if (!a_stream) ... and while (a_stream) ...
   */
 #if __cplusplus >= 201103L
+  _GLIBCXX_NODISCARD
   explicit operator bool() const
   { return !this->fail(); }
 #else
@@ -127,6 +128,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   { return this->fail() ? 0 : const_cast(this); }
 #endif
 
+  _GLIBCXX_NODISCARD
   bool
   operator!() const
   { return this->fail(); }
@@ -139,6 +141,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  See std::ios_base::iostate for the possible bit values.  Most
*  users will call one of the interpreting wrappers, e.g., good().
   */
+  _GLIBCXX_NODISCARD
   iostate
   rdstate() const
   { return _M_streambuf_state; }
@@ -182,6 +185,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
*  A wrapper around rdstate.
   */
+  _GLIBCXX_NODISCARD
   bool
   good() const
   { return this->rdstate() == 0; }
@@ -192,6 +196,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
*  Note that other iostate flags may also be set.
   */
+  _GLIBCXX_NODISCARD
   bool
   eof() const
   { return (this->rdstate() & eofbit) != 0; }
@@ -203,6 +208,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  Checking the badbit in fail() is historical practice.
*  Note that other iostate flags may also be set.
   */
+  _GLIBCXX_NODISCARD
   bool
   fail() const
   { return (this->rdstate() & (badbit | failbit)) != 0; }
@@ -213,6 +219,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
*  Note that other iostate flags may also be set.
   */
+  _GLIBCXX_NODISCARD
   bool
   bad() const
   { return (this->rdstate() & badbit) != 0; }
@@ -224,6 +231,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  This changes nothing in the stream.  See the one-argument version
*  of exceptions(iostate) for the meaning of the return value.
   */
+  _GLIBCXX_NODISCARD
   iostate
   exceptions() const
   { return _M_exception; }
@@ -297,6 +305,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 

[gcc r14-10708] libstdc++: Avoid forming T* in unique_ptr(auto_ptr&&) constraints [PR116529]

2024-09-23 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:4d88724c2d804e126d63aed77fa8c2c333e99396

commit r14-10708-g4d88724c2d804e126d63aed77fa8c2c333e99396
Author: Jonathan Wakely 
Date:   Thu Aug 29 13:47:15 2024 +0100

libstdc++: Avoid forming T* in unique_ptr(auto_ptr&&) constraints 
[PR116529]

PR 116529 shows that std::unique_ptr is currently unusable
because the constructor taking std::auto_ptr (which is a non-standard
extension since C++17) tries to form the invalid type X&* during
overload resolution. We can use the `pointer` type in the constructor
constraints, instead of trying to form an invalid type. The
std::auto_ptr constructor can never actually match for the case where
element_type is a reference, so we just need it to produce a
substitution failure instead of being ill-formed.

LWG 4144 might make std::unique_ptr ill-formed, which would
invalidate this new test. We would have to remove this test in that
case. Using `pointer` in the constructor from std::auto_ptr would not be
needed to support the std::unique_ptr case, but would not cause
any harm either.

libstdc++-v3/ChangeLog:

PR libstdc++/116529
* include/bits/unique_ptr.h (unique_ptr(auto_ptr&&)):
Use pointer instead of T*.
* testsuite/20_util/unique_ptr/creation/116529.cc: New test.

(cherry picked from commit a001d515059ba4647169f8c17967d08bbe41cb7a)

Diff:
---
 libstdc++-v3/include/bits/unique_ptr.h |  5 ++--
 .../20_util/unique_ptr/creation/116529.cc  | 35 ++
 2 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/bits/unique_ptr.h 
b/libstdc++-v3/include/bits/unique_ptr.h
index 0f600db32f94..edcff78bff9f 100644
--- a/libstdc++-v3/include/bits/unique_ptr.h
+++ b/libstdc++-v3/include/bits/unique_ptr.h
@@ -379,8 +379,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
   /// Converting constructor from @c auto_ptr
-  template, is_same<_Dp, default_delete<_Tp
+  template,
+  is_same<_Dp, default_delete<_Tp
unique_ptr(auto_ptr<_Up>&& __u) noexcept;
 #pragma GCC diagnostic pop
 #endif
diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/creation/116529.cc 
b/libstdc++-v3/testsuite/20_util/unique_ptr/creation/116529.cc
new file mode 100644
index ..323fc7cb27ce
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/unique_ptr/creation/116529.cc
@@ -0,0 +1,35 @@
+// { dg-do run { target c++11 } }
+
+// Bug libstdc++/116529 - Construction of unique_ptr with reference type
+// is rejected because of auto_ptr constructor
+
+#include 
+#include 
+
+int count = 0;
+
+struct X
+{
+  ~X() { ++count; }
+};
+
+struct deleter : std::default_delete
+{
+  using pointer = X*;
+};
+
+void
+test01()
+{
+  {
+std::unique_ptr up(new X);
+// { dg-bogus "forming pointer to reference" "" { target *-*-* } 0 }
+VERIFY( count == 0 );
+  }
+  VERIFY( count == 1 );
+}
+
+int main()
+{
+  test01();
+}


[gcc r14-10706] libstdc++: Document missing features for old std:string ABI [PR116777]

2024-09-23 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:74f67ba3dcfd09209bed6265772d5fd9007ea605

commit r14-10706-g74f67ba3dcfd09209bed6265772d5fd9007ea605
Author: Jonathan Wakely 
Date:   Fri Sep 20 17:35:48 2024 +0100

libstdc++: Document missing features for old std:string ABI [PR116777]

There are several features that are not supported when using the old
std::string ABI. It's possible that PR 81967 will get fixed, but the
missing C++20 features almost certainly won't be. Document this in the
manual.

libstdc++-v3/ChangeLog:

PR libstdc++/116777
* doc/xml/manual/using.xml: Document features that are not
supported for the gcc4-compatible ABI.
* doc/html/manual/using_dual_abi.html: Regenerate.

(cherry picked from commit 82309222300acf68e345b32155df21e1b876144e)

Diff:
---
 libstdc++-v3/doc/html/manual/using_dual_abi.html | 18 +++-
 libstdc++-v3/doc/xml/manual/using.xml| 26 +++-
 2 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/doc/html/manual/using_dual_abi.html 
b/libstdc++-v3/doc/html/manual/using_dual_abi.html
index 916ac575f64b..939eedae3629 100644
--- a/libstdc++-v3/doc/html/manual/using_dual_abi.html
+++ b/libstdc++-v3/doc/html/manual/using_dual_abi.html
@@ -22,7 +22,7 @@
   of the macro is 1 which causes the new ABI to 
be active,
   so to use the old ABI you must explicitly define the macro to
   0 before including any library headers.
-  (Be aware that some GNU/Linux distributions configure GCC 5 differently so
+  (Be aware that some GNU/Linux distributions configured GCC 5 differently so
   that the default value of the macro is 0 and 
users must
   define it to 1 to enable the new ABI.)
  Although the changes were made for C++11 conformance, the choice of ABI
@@ -72,6 +72,22 @@
   Handlers for std::exception will always catch
   iostreams exceptions, because the old and new type both inherit from
   std::exception.
+
+  Some features are not supported when using the old ABI, including:
+  
+Using std::string::const_iterator for
+positional arguments to member functions such as
+std::string::erase.
+  
+Allocator propagation in std::string.
+  
+Using std::string at compile-time in
+constexpr functions.
+  
+Class std::chrono::time_zone and all 
related APIs.
+  
+The  header.
+  
 Troubleshooting
 If you get linker errors about undefined references to symbols
   that involve types in the std::__cxx11 namespace 
or the tag
   [abi:cxx11] then it probably indicates that you 
are trying to
diff --git a/libstdc++-v3/doc/xml/manual/using.xml 
b/libstdc++-v3/doc/xml/manual/using.xml
index 2baa99205173..92d3c0ed6b86 100644
--- a/libstdc++-v3/doc/xml/manual/using.xml
+++ b/libstdc++-v3/doc/xml/manual/using.xml
@@ -1356,7 +1356,7 @@ g++ -Winvalid-pch -I. -include stdc++.h -H -g -O2 
hello.cc -o test.exe
   of the macro is 1 which causes the new ABI to be active,
   so to use the old ABI you must explicitly define the macro to
   0 before including any library headers.
-  (Be aware that some GNU/Linux distributions configure GCC 5 differently so
+  (Be aware that some GNU/Linux distributions configured GCC 5 differently so
   that the default value of the macro is 0 and users must
   define it to 1 to enable the new ABI.)
 
@@ -1416,6 +1416,30 @@ g++ -Winvalid-pch -I. -include stdc++.h -H -g -O2 
hello.cc -o test.exe
   std::exception.
 
 
+
+  Some features are not supported when using the old ABI, including:
+  
+  
+Using std::string::const_iterator for
+positional arguments to member functions such as
+std::string::erase.
+  
+  
+Allocator propagation in std::string.
+  
+  
+Using std::string at compile-time in
+constexpr functions.
+  
+  
+Class std::chrono::time_zone and all related APIs.
+  
+  
+The  header.
+  
+  
+
+
 Troubleshooting
 
  If you get linker errors about undefined references to symbols


[gcc r15-3775] libstdc++: Fix condition for ranges::copy to use memmove [PR116754]

2024-09-22 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:83c6fe130a00c6c28cfffcc787a0a719966adfaf

commit r15-3775-g83c6fe130a00c6c28cfffcc787a0a719966adfaf
Author: Jonathan Wakely 
Date:   Wed Sep 18 17:47:49 2024 +0100

libstdc++: Fix condition for ranges::copy to use memmove [PR116754]

libstdc++-v3/ChangeLog:

PR libstdc++/116754
* include/bits/ranges_algobase.h (__copy_or_move): Fix order of
arguments to __memcpyable.

Diff:
---
 libstdc++-v3/include/bits/ranges_algobase.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/bits/ranges_algobase.h 
b/libstdc++-v3/include/bits/ranges_algobase.h
index 2a36ba69775a..40c628b38182 100644
--- a/libstdc++-v3/include/bits/ranges_algobase.h
+++ b/libstdc++-v3/include/bits/ranges_algobase.h
@@ -286,7 +286,7 @@ namespace ranges
{
  if (!std::__is_constant_evaluated())
{
- if constexpr (__memcpyable<_Iter, _Out>::__value)
+ if constexpr (__memcpyable<_Out, _Iter>::__value)
{
  using _ValueTypeI = iter_value_t<_Iter>;
  auto __num = __last - __first;


[gcc r15-3774] libstdc++: Fix formatting of most negative chrono::duration [PR116755]

2024-09-22 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:482e651f5750e4648ade90e32ed45b094538e7f8

commit r15-3774-g482e651f5750e4648ade90e32ed45b094538e7f8
Author: Jonathan Wakely 
Date:   Wed Sep 18 17:20:29 2024 +0100

libstdc++: Fix formatting of most negative chrono::duration [PR116755]

When formatting chrono::duration::min() we were
causing undefined behaviour by trying to form the negative of the most
negative value. If we convert negative durations with integer rep to the
corresponding unsigned integer rep then we can safely represent all
values.

libstdc++-v3/ChangeLog:

PR libstdc++/116755
* include/bits/chrono_io.h (formatter>::format):
Cast negative integral durations to unsigned rep.
* testsuite/20_util/duration/io.cc: Test the most negative
integer durations.

Diff:
---
 libstdc++-v3/include/bits/chrono_io.h | 16 ++--
 libstdc++-v3/testsuite/20_util/duration/io.cc |  8 
 2 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/bits/chrono_io.h 
b/libstdc++-v3/include/bits/chrono_io.h
index 0e4d23c9bb77..c7d2c9862fcf 100644
--- a/libstdc++-v3/include/bits/chrono_io.h
+++ b/libstdc++-v3/include/bits/chrono_io.h
@@ -1720,8 +1720,20 @@ namespace __format
   basic_format_context<_Out, _CharT>& __fc) const
{
  if constexpr (numeric_limits<_Rep>::is_signed)
-   if (__d < __d.zero())
- return _M_f._M_format(-__d, __fc, true);
+   if (__d < __d.zero()) [[unlikely]]
+ {
+   if constexpr (is_integral_v<_Rep>)
+ {
+   // -d is undefined for the most negative integer.
+   // Convert duration to corresponding unsigned rep.
+   using _URep = make_unsigned_t<_Rep>;
+   auto __ucnt = -static_cast<_URep>(__d.count());
+   auto __ud = chrono::duration<_URep, _Period>(__ucnt);
+   return _M_f._M_format(__ud, __fc, true);
+ }
+   else
+ return _M_f._M_format(-__d, __fc, true);
+ }
  return _M_f._M_format(__d, __fc, false);
}
 
diff --git a/libstdc++-v3/testsuite/20_util/duration/io.cc 
b/libstdc++-v3/testsuite/20_util/duration/io.cc
index 6b00689672c8..57020f4f9537 100644
--- a/libstdc++-v3/testsuite/20_util/duration/io.cc
+++ b/libstdc++-v3/testsuite/20_util/duration/io.cc
@@ -106,6 +106,14 @@ test_format()
   VERIFY( s == "500ms" );
   s = std::format("{:%Q %q}", u);
   VERIFY( s == "500 ms" );
+
+  // PR libstdc++/116755 extra minus sign for most negative value
+  auto minsec = std::chrono::seconds::min();
+  s = std::format("{}", minsec);
+  auto expected = std::format("{}s", minsec.count());
+  VERIFY( s == expected );
+  s = std::format("{:%Q%q}", minsec);
+  VERIFY( s == expected );
 }
 
 void


[gcc r15-3773] libstdc++: Use constexpr instead of _GLIBCXX20_CONSTEXPR in

2024-09-22 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:b6463161c3cd0b1f764697290d9569c7153b8a5b

commit r15-3773-gb6463161c3cd0b1f764697290d9569c7153b8a5b
Author: Jonathan Wakely 
Date:   Wed Sep 18 16:17:28 2024 +0100

libstdc++: Use constexpr instead of _GLIBCXX20_CONSTEXPR in 

For the operator<=> overload we can use the 'constexpr' keyword
directly, because we know the language dialect is at least C++20.

libstdc++-v3/ChangeLog:

* include/bits/stl_vector.h (operator<=>): Use constexpr
instead of _GLIBCXX20_CONSTEXPR macro.

Diff:
---
 libstdc++-v3/include/bits/stl_vector.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/libstdc++-v3/include/bits/stl_vector.h 
b/libstdc++-v3/include/bits/stl_vector.h
index 182ad41ed946..e284536ad31e 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -2078,7 +2078,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 { return (__x.size() == __y.size()
  && std::equal(__x.begin(), __x.end(), __y.begin())); }
 
-#if __cpp_lib_three_way_comparison
+#if __cpp_lib_three_way_comparison // >= C++20
   /**
*  @brief  Vector ordering relation.
*  @param  __x  A `vector`.
@@ -2091,8 +2091,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*  `<` and `>=` etc.
   */
   template
-[[nodiscard]] _GLIBCXX20_CONSTEXPR
-inline __detail::__synth3way_t<_Tp>
+[[nodiscard]]
+constexpr __detail::__synth3way_t<_Tp>
 operator<=>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
 {
   return std::lexicographical_compare_three_way(__x.begin(), __x.end(),


[gcc r15-3652] libstdc++: Enable most of for freestanding

2024-09-15 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:1dde83f0ec313166fc91e6784a0ca2e3db46acee

commit r15-3652-g1dde83f0ec313166fc91e6784a0ca2e3db46acee
Author: Jonathan Wakely 
Date:   Mon Jan 15 14:09:21 2024 +

libstdc++: Enable most of  for freestanding

This makes durations, time points and calendrical types available for
freestanding. The clocks and time zone utilities are disabled for
freestanding, as they require functions in the hosted lib.

Add support for a new macro _GLIBCXX_NO_FREESTANDING_CHRONO which can be
used to explicitly disable  for freestanding.

libstdc++-v3/ChangeLog:

* doc/xml/manual/using.xml (_GLIBCXX_NO_FREESTANDING_CHRONO):
Document macro.
* doc/html/*: Regenerate.
* include/bits/chrono.h [_GLIBCXX_NO_FREESTANDING_CHRONO]:
Only include  when this macro is defined.
[_GLIBCXX_HOSTED]: Only define clocks for hosted.
* include/bits/version.def (chrono_udls): Remove hosted=yes.
* include/bits/version.h: Regenerate.
* include/std/chrono [_GLIBCXX_HOSTED]: Only define clocks and
time zone utilities for hosted.
* testsuite/std/time/freestanding.cc: New test.

Diff:
---
 libstdc++-v3/doc/html/manual/using_macros.html  |  7 
 libstdc++-v3/doc/xml/manual/using.xml   | 12 ++
 libstdc++-v3/include/bits/chrono.h  | 24 +---
 libstdc++-v3/include/bits/version.def   |  1 -
 libstdc++-v3/include/bits/version.h |  2 +-
 libstdc++-v3/include/std/chrono | 24 +---
 libstdc++-v3/testsuite/std/time/freestanding.cc | 52 +
 7 files changed, 109 insertions(+), 13 deletions(-)

diff --git a/libstdc++-v3/doc/html/manual/using_macros.html 
b/libstdc++-v3/doc/html/manual/using_macros.html
index ae5646926307..67623b5e2aff 100644
--- a/libstdc++-v3/doc/html/manual/using_macros.html
+++ b/libstdc++-v3/doc/html/manual/using_macros.html
@@ -124,4 +124,11 @@
 must be present on all vector operations or none, so this macro must
 be defined to the same value for all translation units that create,
 destroy, or modify vectors.
+  _GLIBCXX_NO_FREESTANDING_CHRONO
+   Undefined by default. When defined, the
+    header cannot
+   be used with -ffreestanding.
+   When not defined, durations, time points, and calendar types are
+   available for freestanding, but the standard clocks and the time zone
+   database are not (because they require OS support).
   Prev Up NextHeaders Home 
Dual ABI
\ No newline at end of file
diff --git a/libstdc++-v3/doc/xml/manual/using.xml 
b/libstdc++-v3/doc/xml/manual/using.xml
index 6675359f3b3c..4e1c70040b56 100644
--- a/libstdc++-v3/doc/xml/manual/using.xml
+++ b/libstdc++-v3/doc/xml/manual/using.xml
@@ -1321,6 +1321,18 @@ g++ -Winvalid-pch -I. -include stdc++.h -H -g -O2 
hello.cc -o test.exe
 destroy, or modify vectors.
   
 
+
+_GLIBCXX_NO_FREESTANDING_CHRONO
+
+  
+   Undefined by default. When defined, the
+    header cannot
+   be used with -ffreestanding.
+   When not defined, durations, time points, and calendar types are
+   available for freestanding, but the standard clocks and the time zone
+   database are not (because they require OS support).
+  
+
 
 
   
diff --git a/libstdc++-v3/include/bits/chrono.h 
b/libstdc++-v3/include/bits/chrono.h
index 0773867da716..fd9c4642f4f2 100644
--- a/libstdc++-v3/include/bits/chrono.h
+++ b/libstdc++-v3/include/bits/chrono.h
@@ -37,7 +37,9 @@
 #include 
 #include 
 #include 
-#include 
+#if _GLIBCXX_HOSTED
+# include 
+#endif
 #include  // for literals support.
 #if __cplusplus >= 202002L
 # include 
@@ -50,7 +52,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-#if __cplusplus >= 201703L
+#if __cplusplus >= 201703L && _GLIBCXX_HOSTED
   namespace filesystem { struct __file_clock; };
 #endif
 
@@ -372,7 +374,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   { };
 #endif // C++20
 
-#ifdef __glibcxx_chrono // C++ >= 17 && HOSTED
+#if __cplusplus >= 201703L // C++ >= 17
 /** Convert a `duration` to type `ToDur` and round down.
  *
  * If the duration cannot be represented exactly in the result type,
@@ -1196,6 +1198,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 /// @}
 /// @} group chrono
 
+#if _GLIBCXX_HOSTED
 // Clocks.
 
 // Why nanosecond resolution as the default?
@@ -1310,9 +1313,18 @@ _GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
 template<> inline constexpr bool is_clock_v = true;
 /// @}
 #endif // C++20
+#elif __cplusplus >= 202002L
+// Define a fake clock like chrono::local_t so that sys_time etc.
+// can be used for freestanding.
+struct __sys_t;
+template
+  using sys_time = time_point<__sys_t, _Duration>;
+using sys_seconds = sys_time;
+using sys_days = sys_tim

[gcc r15-3639] libstdc++: Refactor loops in std::__platform_semaphore

2024-09-14 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:01670a4095791733e0389acead832e3da757c9d7

commit r15-3639-g01670a4095791733e0389acead832e3da757c9d7
Author: Jonathan Wakely 
Date:   Mon Sep 2 12:29:04 2024 +0100

libstdc++: Refactor loops in std::__platform_semaphore

Refactor the loops to all use the same form, and to not need explicit
'break' or 'continue' jumps. This also avoids a -Wunused-variable
warning with -Wsystem-headers.

Also fix a bug for absolute timeouts specified with a time that isn't
implicitly convertible to __clock_t::time_point, e.g. one with a higher
resolution such as picoseconds. Use chrono::ceil to round up to the next
time point representable by the clock.

libstdc++-v3/ChangeLog:

* include/bits/semaphore_base.h (__platform_semaphore): Refactor
loops to all use similar forms.
(__platform_semaphore::_M_try_acquire_until): Use chrono::ceil
to explicitly convert to __clock_t::time_point.
* testsuite/30_threads/semaphore/try_acquire_for.cc: Check that
using a very high resolution timeout compiles.
* testsuite/30_threads/semaphore/platform_try_acquire_for.cc:
New test.

Diff:
---
 libstdc++-v3/include/bits/semaphore_base.h | 58 --
 .../semaphore/platform_try_acquire_for.cc  |  7 +++
 .../30_threads/semaphore/try_acquire_for.cc| 13 +
 3 files changed, 40 insertions(+), 38 deletions(-)

diff --git a/libstdc++-v3/include/bits/semaphore_base.h 
b/libstdc++-v3/include/bits/semaphore_base.h
index 44a68645e477..2b19c9c6c6ac 100644
--- a/libstdc++-v3/include/bits/semaphore_base.h
+++ b/libstdc++-v3/include/bits/semaphore_base.h
@@ -73,52 +73,37 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 _GLIBCXX_ALWAYS_INLINE void
 _M_acquire() noexcept
 {
-  for (;;)
-   {
- auto __err = sem_wait(&_M_semaphore);
- if (__err && (errno == EINTR))
-   continue;
- else if (__err)
-   std::__terminate();
- else
-   break;
-   }
+  while (sem_wait(&_M_semaphore))
+   if (errno != EINTR)
+ std::__terminate();
 }
 
 _GLIBCXX_ALWAYS_INLINE bool
 _M_try_acquire() noexcept
 {
-  for (;;)
+  while (sem_trywait(&_M_semaphore))
{
- auto __err = sem_trywait(&_M_semaphore);
- if (__err && (errno == EINTR))
-   continue;
- else if (__err && (errno == EAGAIN))
+ if (errno == EAGAIN) // already locked
return false;
- else if (__err)
+ else if (errno != EINTR)
std::__terminate();
- else
-   break;
+ // else got EINTR so retry
}
   return true;
 }
 
 _GLIBCXX_ALWAYS_INLINE void
-_M_release(std::ptrdiff_t __update) noexcept
+_M_release(ptrdiff_t __update) noexcept
 {
   for(; __update != 0; --__update)
-   {
-  auto __err = sem_post(&_M_semaphore);
-  if (__err)
-std::__terminate();
-   }
+   if (sem_post(&_M_semaphore))
+ std::__terminate();
 }
 
 bool
 _M_try_acquire_until_impl(const chrono::time_point<__clock_t>& __atime)
   noexcept
 {
-
   auto __s = chrono::time_point_cast(__atime);
   auto __ns = chrono::duration_cast(__atime - __s);
 
@@ -128,19 +113,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static_cast(__ns.count())
   };
 
-  for (;;)
+  while (sem_timedwait(&_M_semaphore, &__ts))
{
- if (auto __err = sem_timedwait(&_M_semaphore, &__ts))
-   {
- if (errno == EINTR)
-   continue;
- else if (errno == ETIMEDOUT || errno == EINVAL)
-   return false;
- else
-   std::__terminate();
-   }
- else
-   break;
+ if (errno == ETIMEDOUT)
+   return false;
+ else if (errno != EINTR)
+   std::__terminate();
}
   return true;
 }
@@ -152,10 +130,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   {
if constexpr (std::is_same_v<__clock_t, _Clock>)
  {
-   return _M_try_acquire_until_impl(__atime);
+   using _Dur = __clock_t::duration;
+   return _M_try_acquire_until_impl(chrono::ceil<_Dur>(__atime));
  }
else
  {
+   // TODO: if _Clock is monotonic_clock we could use
+   // sem_clockwait with CLOCK_MONOTONIC.
+
const typename _Clock::time_point __c_entry = _Clock::now();
const auto __s_entry = __clock_t::now();
const auto __delta = __atime - __c_entry;
diff --git 
a/libstdc++-v3/testsuite/30_threads/semaphore/platform_try_acquire_for.cc 
b/libstdc++-v3/testsuite/30_threads/semaphore/platform_try_acquire_for.cc
new file mode 100644
index ..bf6cd142bf01
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/semaphore/platform_try_acquire_for.

[gcc r15-3637] c++: Fix g++.dg/ext/sve-sizeless-1.C regression

2024-09-14 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:bec1f2ce4ad3fe56906d6429b542a290e574b3eb

commit r15-3637-gbec1f2ce4ad3fe56906d6429b542a290e574b3eb
Author: Jonathan Wakely 
Date:   Fri Sep 13 08:18:53 2024 +0100

c++: Fix g++.dg/ext/sve-sizeless-1.C regression

This aarch64-*-* test needs an update for the diagnostic I changed in
r15-3614-g9fe57e4879de93.

gcc/testsuite/ChangeLog:

* g++.dg/ext/sve-sizeless-1.C: Adjust dg-error string.

Diff:
---
 gcc/testsuite/g++.dg/ext/sve-sizeless-1.C | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/g++.dg/ext/sve-sizeless-1.C 
b/gcc/testsuite/g++.dg/ext/sve-sizeless-1.C
index 9f05ca5a855a..adee37a0551e 100644
--- a/gcc/testsuite/g++.dg/ext/sve-sizeless-1.C
+++ b/gcc/testsuite/g++.dg/ext/sve-sizeless-1.C
@@ -301,7 +301,7 @@ statements (int n)
 
   // Other built-ins
 
-  __builtin_launder (sve_sc1); // { dg-error {non-pointer argument to 
'__builtin_launder'} }
+  __builtin_launder (sve_sc1); // { dg-error {not a pointer to object type} }
   __builtin_memcpy (&sve_sc1, &sve_sc2, 2);
 
   // Lambdas


[gcc r15-3614] c++: Make __builtin_launder reject invalid types [PR116673]

2024-09-12 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:9fe57e4879de93b6e3c7b4c226f42d5f3a48474f

commit r15-3614-g9fe57e4879de93b6e3c7b4c226f42d5f3a48474f
Author: Jonathan Wakely 
Date:   Wed Sep 11 11:47:44 2024 +0100

c++: Make __builtin_launder reject invalid types [PR116673]

The standard says that std::launder is ill-formed for function pointers
and cv void pointers, so there's no reason for __builtin_launder to
accept them. This change allows implementations of std::launder to defer
to the built-in for error checking, although libstdc++ will continue to
diagnose it directly for more user-friendly diagnostics.

PR c++/116673

gcc/cp/ChangeLog:

* semantics.cc (finish_builtin_launder): Diagnose function
pointers and cv void pointers.

gcc/testsuite/ChangeLog:

* g++.dg/cpp1z/launder2.C: Adjust dg-error strings.
* g++.dg/cpp1z/launder10.C: New test.

Diff:
---
 gcc/cp/semantics.cc|  6 +++---
 gcc/testsuite/g++.dg/cpp1z/launder10.C | 15 +++
 gcc/testsuite/g++.dg/cpp1z/launder2.C  |  6 +++---
 3 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 63212afafb3b..8219d6410b8e 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -13482,10 +13482,10 @@ finish_builtin_launder (location_t loc, tree arg, 
tsubst_flags_t complain)
 arg = decay_conversion (arg, complain);
   if (error_operand_p (arg))
 return error_mark_node;
-  if (!type_dependent_expression_p (arg)
-  && !TYPE_PTR_P (TREE_TYPE (arg)))
+  if (!type_dependent_expression_p (arg) && !TYPE_PTROB_P (TREE_TYPE (arg)))
 {
-  error_at (loc, "non-pointer argument to %<__builtin_launder%>");
+  error_at (loc, "type %qT of argument to %<__builtin_launder%> "
+   "is not a pointer to object type", TREE_TYPE (arg));
   return error_mark_node;
 }
   if (processing_template_decl)
diff --git a/gcc/testsuite/g++.dg/cpp1z/launder10.C 
b/gcc/testsuite/g++.dg/cpp1z/launder10.C
new file mode 100644
index ..2109a2e38393
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/launder10.C
@@ -0,0 +1,15 @@
+// PR c++/116673
+// { dg-do compile }
+
+void
+bar (void *p)
+{
+  __builtin_launder (bar); // { dg-error {argument to '__builtin_launder'} }
+  __builtin_launder (p);   // { dg-error {argument to '__builtin_launder'} }
+  const void* cp = p;
+  __builtin_launder (cp);  // { dg-error {argument to '__builtin_launder'} }
+  volatile void* vp = p;
+  __builtin_launder (vp);  // { dg-error {argument to '__builtin_launder'} }
+  const volatile void* cvp = p;
+  __builtin_launder (cvp); // { dg-error {argument to '__builtin_launder'} }
+}
diff --git a/gcc/testsuite/g++.dg/cpp1z/launder2.C 
b/gcc/testsuite/g++.dg/cpp1z/launder2.C
index 9cd1779704b3..a2d448612655 100644
--- a/gcc/testsuite/g++.dg/cpp1z/launder2.C
+++ b/gcc/testsuite/g++.dg/cpp1z/launder2.C
@@ -4,11 +4,11 @@ int a;
 int *b = __builtin_launder (); // { dg-error "wrong number of 
arguments to" }
 int *c = __builtin_launder (&a, 2);// { dg-error "wrong number of 
arguments to" }
 int *d = __builtin_launder (&a);
-int e = __builtin_launder (a); // { dg-error "non-pointer argument to" 
}
+int e = __builtin_launder (a); // { dg-error "not a pointer to object 
type" }
 int &f = a;
-int g = __builtin_launder (f); // { dg-error "non-pointer argument to" 
}
+int g = __builtin_launder (f); // { dg-error "not a pointer to object 
type" }
 
-template  T f1 (T x) { return __builtin_launder (x); } // { 
dg-error "non-pointer argument to" }
+template  T f1 (T x) { return __builtin_launder (x); } // { 
dg-error "not a pointer to object type" }
 template  T f2 (T x) { return __builtin_launder (x); }
 
 int h = f1 (a);


[gcc r15-3575] libstdc++: std::string move assignment should not use POCCA trait [PR116641]

2024-09-10 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:c07cf418fdde0c192e370a8d76a991cc7215e9c4

commit r15-3575-gc07cf418fdde0c192e370a8d76a991cc7215e9c4
Author: Jonathan Wakely 
Date:   Tue Sep 10 14:25:41 2024 +0100

libstdc++: std::string move assignment should not use POCCA trait [PR116641]

The changes to implement LWG 2579 (r10-327-gdb33efde17932f) made
std::string::assign use the propagate_on_container_copy_assignment
(POCCA) trait, for consistency with operator=(const basic_string&).
However, this also unintentionally affected operator=(basic_string&&)
which calls assign(str) to make a deep copy when performing a move is
not possible. The fix is for the move assignment operator to call
_M_assign(str) instead of assign(str), as this just does the deep copy
and doesn't check the POCCA trait first.

The bug only affects the unlikely/useless combination of POCCA==true and
POCMA==false, but we should fix it for correctness anyway. it should
also make move assignment slightly cheaper to compile and execute,
because we skip the extra code in assign(const basic_string&).

libstdc++-v3/ChangeLog:

PR libstdc++/116641
* include/bits/basic_string.h (operator=(basic_string&&)): Call
_M_assign instead of assign.
* testsuite/21_strings/basic_string/allocator/116641.cc: New
test.

Diff:
---
 libstdc++-v3/include/bits/basic_string.h   |  2 +-
 .../21_strings/basic_string/allocator/116641.cc| 53 ++
 2 files changed, 54 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/bits/basic_string.h 
b/libstdc++-v3/include/bits/basic_string.h
index 944bd230704b..120c0bc9a179 100644
--- a/libstdc++-v3/include/bits/basic_string.h
+++ b/libstdc++-v3/include/bits/basic_string.h
@@ -915,7 +915,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
  __str._M_data(__str._M_use_local_data());
  }
else // Need to do a deep copy
- assign(__str);
+ _M_assign(__str);
__str.clear();
return *this;
   }
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/allocator/116641.cc 
b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/116641.cc
new file mode 100644
index ..a1a411b87faa
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/allocator/116641.cc
@@ -0,0 +1,53 @@
+// { dg-do run { target c++11 } }
+// { dg-require-effective-target cxx11_abi }
+
+// Bug 116641 - std::string move assignment incorrectly depends on POCCA
+
+#include 
+#include 
+
+template
+struct Alloc
+{
+  using value_type = T;
+  using propagate_on_container_swap = std::false_type;
+  using propagate_on_container_copy_assignment = std::true_type;
+  using propagate_on_container_move_assignment = std::false_type;
+
+  Alloc(int id) : id(id) { }
+
+  template
+Alloc(const Alloc& a) : id(a.id) { }
+
+  T* allocate(unsigned long n)
+  { return std::allocator().allocate(n); }
+
+  void deallocate(T* p, unsigned long n)
+  { std::allocator().deallocate(p, n); }
+
+  Alloc& operator=(const Alloc&) { throw; }
+
+  bool operator==(const Alloc& a) const { return id == a.id; }
+  bool operator!=(const Alloc& a) const { return id != a.id; }
+
+  int id;
+};
+
+void
+test_pr116641()
+{
+  Alloc a1(1), a2(2);
+  std::basic_string, Alloc> s1(a1), s2(a2);
+
+  s1 = "allocator should not propagate on move assignment";
+  VERIFY( s1.get_allocator() == a1 );
+  VERIFY( s2.get_allocator() == a2 );
+  s2 = std::move(s1);
+  VERIFY( s1.get_allocator() == a1 );
+  VERIFY( s2.get_allocator() == a2 );
+}
+
+int main()
+{
+  test_pr116641();
+}


[gcc r15-3573] libstdc++: Add missing exception specifications in tests

2024-09-10 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:4e1e50458b2004d0f08ac8c64f89b85fc1a87057

commit r15-3573-g4e1e50458b2004d0f08ac8c64f89b85fc1a87057
Author: Jonathan Wakely 
Date:   Tue Sep 10 16:59:29 2024 +0100

libstdc++: Add missing exception specifications in tests

Since r15-3532-g7cebc6384a0ad6 18_support/new_nothrow.cc fails in C++98 
mode because G++
diagnoses missing exception specifications for the user-defined
(de)allocation functions. Add throw(std::bad_alloc) and throw() for
C++98 mode.

Similarly, 26_numerics/headers/numeric/synopsis.cc fails in C++20 mode
because the declarations of gcd and lcm are not noexcept.

libstdc++-v3/ChangeLog:

* testsuite/18_support/new_nothrow.cc (THROW_BAD_ALLOC): Define
macro to add exception specifications for C++98 mode.
(NOEXCEPT): Expand to throw() for C++98 mode.
* testsuite/26_numerics/headers/numeric/synopsis.cc (gcd, lcm):
Add noexcept.

Diff:
---
 libstdc++-v3/testsuite/18_support/new_nothrow.cc   | 18 ++
 .../testsuite/26_numerics/headers/numeric/synopsis.cc  |  4 ++--
 2 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/libstdc++-v3/testsuite/18_support/new_nothrow.cc 
b/libstdc++-v3/testsuite/18_support/new_nothrow.cc
index a3251f5ad64e..551b71dfa589 100644
--- a/libstdc++-v3/testsuite/18_support/new_nothrow.cc
+++ b/libstdc++-v3/testsuite/18_support/new_nothrow.cc
@@ -41,7 +41,15 @@ static void new_handler ()
 throw MyBadAlloc ();
 }
 
-void* operator new (size_t n)
+#if __cplusplus >= 201103L
+# define THROW_BAD_ALLOC noexcept(false)
+# define NOEXCEPT noexcept
+# else
+# define THROW_BAD_ALLOC throw(std::bad_alloc)
+# define NOEXCEPT throw()
+#endif
+
+void* operator new (size_t n) THROW_BAD_ALLOC
 {
 static size_t cntr;
 
@@ -64,12 +72,6 @@ void* operator new (size_t n)
 }
 }
 
-#if __cplusplus >= 201103L
-#define NOEXCEPT noexcept
-#else
-#define NOEXCEPT
-#endif
-
 void operator delete (void *p) NOEXCEPT
 {
 ++delete_called;
@@ -77,7 +79,7 @@ void operator delete (void *p) NOEXCEPT
 free (static_cast(p) - 1);
 }
 
-void* operator new[] (size_t n)
+void* operator new[] (size_t n) THROW_BAD_ALLOC
 {
 ++new_vec_called;
 return operator new(n);
diff --git a/libstdc++-v3/testsuite/26_numerics/headers/numeric/synopsis.cc 
b/libstdc++-v3/testsuite/26_numerics/headers/numeric/synopsis.cc
index 87670090f72f..8c33974c2e96 100644
--- a/libstdc++-v3/testsuite/26_numerics/headers/numeric/synopsis.cc
+++ b/libstdc++-v3/testsuite/26_numerics/headers/numeric/synopsis.cc
@@ -161,10 +161,10 @@ namespace std {
 
 #if __cplusplus > 201703L
   template
-constexpr common_type_t gcd(M m, N n);
+constexpr common_type_t gcd(M m, N n) noexcept;
 
   template
-constexpr common_type_t lcm(M m, N n);
+constexpr common_type_t lcm(M m, N n) noexcept;
 
   template
 constexpr T midpoint(T a, T b) noexcept;


[gcc r14-10640] libstdc++: Fix overwriting files with fs::copy_file on Windows

2024-09-04 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:35c98149a5c7af9159fa7615d8d827b3aaa3cc97

commit r14-10640-g35c98149a5c7af9159fa7615d8d827b3aaa3cc97
Author: Jonathan Wakely 
Date:   Tue Jul 30 10:55:55 2024 +0100

libstdc++: Fix overwriting files with fs::copy_file on Windows

There are no inode numbers on Windows filesystems, so stat_type::st_ino
is always zero and the check for equivalent files in do_copy_file was
incorrectly identifying distinct files as equivalent. This caused
copy_file to incorrectly report errors when trying to overwrite existing
files.

The fs::equivalent function already does the right thing on Windows, so
factor that logic out into a new function that can be reused by
fs::copy_file.

The tests for fs::copy_file were quite inadequate, so this also adds
checks for that function's error conditions.

libstdc++-v3/ChangeLog:

* src/c++17/fs_ops.cc (auto_win_file_handle): Change constructor
parameter from const path& to const wchar_t*.
(fs::equiv_files): New function.
(fs::equivalent): Use equiv_files.
* src/filesystem/ops-common.h (fs::equiv_files): Declare.
(do_copy_file): Use equiv_files.
* src/filesystem/ops.cc (fs::equiv_files): Define.
(fs::copy, fs::equivalent): Use equiv_files.
* testsuite/27_io/filesystem/operations/copy.cc: Test
overwriting directory contents recursively.
* testsuite/27_io/filesystem/operations/copy_file.cc: Test
overwriting existing files.

(cherry picked from commit 017e3f89b081e4828a588a3bd27b5feacea042b7)

Diff:
---
 libstdc++-v3/src/c++17/fs_ops.cc   |  71 +++-
 libstdc++-v3/src/filesystem/ops-common.h   |  12 +-
 libstdc++-v3/src/filesystem/ops.cc |  18 ++-
 .../testsuite/27_io/filesystem/operations/copy.cc  |   9 ++
 .../27_io/filesystem/operations/copy_file.cc   | 122 +
 5 files changed, 199 insertions(+), 33 deletions(-)

diff --git a/libstdc++-v3/src/c++17/fs_ops.cc b/libstdc++-v3/src/c++17/fs_ops.cc
index 81227c49dfd..9606afa9f1f 100644
--- a/libstdc++-v3/src/c++17/fs_ops.cc
+++ b/libstdc++-v3/src/c++17/fs_ops.cc
@@ -350,7 +350,7 @@ fs::copy(const path& from, const path& to, copy_options 
options,
   f = make_file_status(from_st);
 
   if (exists(t) && !is_other(t) && !is_other(f)
-  && to_st.st_dev == from_st.st_dev && to_st.st_ino == from_st.st_ino)
+  && fs::equiv_files(from.c_str(), from_st, to.c_str(), to_st, ec))
 {
   ec = std::make_error_code(std::errc::file_exists);
   return;
@@ -829,8 +829,8 @@ namespace
   struct auto_win_file_handle
   {
 explicit
-auto_win_file_handle(const fs::path& p_)
-: handle(CreateFileW(p_.c_str(), 0,
+auto_win_file_handle(const wchar_t* p)
+: handle(CreateFileW(p, 0,
 FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0))
 { }
@@ -850,6 +850,44 @@ namespace
 }
 #endif
 
+#ifdef _GLIBCXX_HAVE_SYS_STAT_H
+#ifdef NEED_DO_COPY_FILE // Only define this once, not in cow-fs_ops.o too
+bool
+fs::equiv_files([[maybe_unused]] const char_type* p1, const stat_type& st1,
+   [[maybe_unused]] const char_type* p2, const stat_type& st2,
+   [[maybe_unused]] error_code& ec)
+{
+#if ! _GLIBCXX_FILESYSTEM_IS_WINDOWS
+  // For POSIX the device ID and inode number uniquely identify a file.
+  return st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino;
+#else
+  // For Windows st_ino is not set, so can't be used to distinguish files.
+  // We can compare modes and device IDs as a cheap initial check:
+  if (st1.st_mode != st2.st_mode || st1.st_dev != st2.st_dev)
+return false;
+
+  // Need to use GetFileInformationByHandle to get more info about the files.
+  auto_win_file_handle h1(p1);
+  auto_win_file_handle h2(p2);
+  if (!h1 || !h2)
+{
+  if (!h1 && !h2)
+   ec = __last_system_error();
+  return false;
+}
+  if (!h1.get_info() || !h2.get_info())
+{
+  ec = __last_system_error();
+  return false;
+}
+  return h1.info.dwVolumeSerialNumber == h2.info.dwVolumeSerialNumber
+  && h1.info.nFileIndexHigh == h2.info.nFileIndexHigh
+  && h1.info.nFileIndexLow == h2.info.nFileIndexLow;
+#endif // _GLIBCXX_FILESYSTEM_IS_WINDOWS
+}
+#endif // NEED_DO_COPY_FILE
+#endif // _GLIBCXX_HAVE_SYS_STAT_H
+
 bool
 fs::equivalent(const path& p1, const path& p2, error_code& ec) noexcept
 {
@@ -881,30 +919,7 @@ fs::equivalent(const path& p1, const path& p2, error_code& 
ec) noexcept
   ec.clear();
   if (is_other(s1) || is_other(s2))
return false;
-#if _GLIBCXX_FILESYSTEM_IS_WINDOWS
-  // st_ino is not set, so can't be used to distinguish files
-  if (st1.st_mode != st2.st_mode || st1.st_dev != st2.st_dev)
-   return false;
-
-  auto_win_fil

[gcc r14-10638] libstdc++: Specialize std::disable_sized_sentinel_for for std::move_iterator [PR116549]

2024-09-04 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:ee37d750262579a81799c5b56fe1ab936a840120

commit r14-10638-gee37d750262579a81799c5b56fe1ab936a840120
Author: Jonathan Wakely 
Date:   Mon Sep 2 11:29:13 2024 +0100

libstdc++: Specialize std::disable_sized_sentinel_for for 
std::move_iterator [PR116549]

LWG 3736 added a partial specialization of this variable template for
two std::move_iterator types. This is needed for the case where the
types satisfy std::sentinel_for and are subtractable, but do not model
the semantics requirements of std::sized_sentinel_for.

libstdc++-v3/ChangeLog:

PR libstdc++/116549
* include/bits/stl_iterator.h (disable_sized_sentinel_for):
Define specialization for two move_iterator types, as per LWG
3736.
* testsuite/24_iterators/move_iterator/lwg3736.cc: New test.

(cherry picked from commit 819deae0a5bee079a7d5582fafaa098c26144ae8)

Diff:
---
 libstdc++-v3/include/bits/stl_iterator.h   |  8 
 .../24_iterators/move_iterator/lwg3736.cc  | 52 ++
 2 files changed, 60 insertions(+)

diff --git a/libstdc++-v3/include/bits/stl_iterator.h 
b/libstdc++-v3/include/bits/stl_iterator.h
index d3823057270..20c0319f3a7 100644
--- a/libstdc++-v3/include/bits/stl_iterator.h
+++ b/libstdc++-v3/include/bits/stl_iterator.h
@@ -1822,6 +1822,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { return _ReturnType(__i); }
 
 #if __cplusplus > 201703L && __glibcxx_concepts
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // 3736.  move_iterator missing disable_sized_sentinel_for specialization
+  template
+requires (!sized_sentinel_for<_Iterator1, _Iterator2>)
+inline constexpr bool
+disable_sized_sentinel_for,
+  move_iterator<_Iterator2>> = true;
+
   // [iterators.common] Common iterators
 
   namespace __detail
diff --git a/libstdc++-v3/testsuite/24_iterators/move_iterator/lwg3736.cc 
b/libstdc++-v3/testsuite/24_iterators/move_iterator/lwg3736.cc
new file mode 100644
index 000..eaf791b3089
--- /dev/null
+++ b/libstdc++-v3/testsuite/24_iterators/move_iterator/lwg3736.cc
@@ -0,0 +1,52 @@
+// { dg-do compile { target c++20 } }
+
+// 3736.  move_iterator missing disable_sized_sentinel_for specialization
+
+#include 
+
+template using MoveIter = std::move_iterator;
+
+using std::sized_sentinel_for;
+using std::disable_sized_sentinel_for;
+
+// These assertions always passed, even without LWG 3736:
+static_assert(sized_sentinel_for, MoveIter>);
+static_assert(sized_sentinel_for, MoveIter>);
+static_assert(not sized_sentinel_for, MoveIter>);
+static_assert(not sized_sentinel_for, std::default_sentinel_t>);
+static_assert(not disable_sized_sentinel_for, MoveIter>);
+
+// These types don't satisfy sized_sentinel_for anyway (because the subtraction
+// is ill-formed) but LWG 3736 makes the variable template explicitly false:
+static_assert(disable_sized_sentinel_for, MoveIter>);
+
+struct Iter
+{
+  using iterator_category = std::random_access_iterator_tag;
+  using value_type = int;
+  using pointer = int*;
+  using reference = int&;
+  using difference_type = long;
+
+  Iter() = default;
+  Iter& operator++();
+  Iter operator++(int);
+  Iter& operator--();
+  Iter operator--(int);
+  reference operator*() const;
+  pointer operator->() const;
+  Iter& operator+=(difference_type);
+  Iter& operator-=(difference_type);
+  friend Iter operator+(Iter, difference_type);
+  friend Iter operator+(difference_type, Iter);
+  friend Iter operator-(Iter, difference_type);
+  friend difference_type operator-(Iter, Iter);
+  bool operator==(Iter) const;
+};
+
+// Specialize the variable template so that Iter is not its own sized sentinel:
+template<> constexpr bool std::disable_sized_sentinel_for = true;
+static_assert( not sized_sentinel_for );
+
+// LWG 3736 means that affects std::move_iterator as well:
+static_assert( not sized_sentinel_for, MoveIter> );


[gcc r14-10637] libstdc++: Add missing feature-test macro in various headers

2024-09-04 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:469602619d32c24382c6f1c3e3d95c3db606c770

commit r14-10637-g469602619d32c24382c6f1c3e3d95c3db606c770
Author: Dhruv Chawla 
Date:   Mon Aug 26 11:09:19 2024 +0530

libstdc++: Add missing feature-test macro in various headers

version.syn#2 requires various headers to define
__cpp_lib_allocator_traits_is_always_equal. Currently, only  was
defining this macro. Implement fixes for the other headers as well.

Signed-off-by: Dhruv Chawla 

libstdc++-v3/ChangeLog:

* include/std/deque: Define macro
__glibcxx_want_allocator_traits_is_always_equal.
* include/std/forward_list: Likewise.
* include/std/list: Likewise.
* include/std/map: Likewise.
* include/std/scoped_allocator: Likewise.
* include/std/set: Likewise.
* include/std/string: Likewise.
* include/std/unordered_map: Likewise.
* include/std/unordered_set: Likewise.
* include/std/vector: Likewise.
* testsuite/20_util/headers/memory/version.cc: New test.
* testsuite/20_util/scoped_allocator/version.cc: Likewise.
* testsuite/21_strings/headers/string/version.cc: Likewise.
* testsuite/23_containers/deque/version.cc: Likewise.
* testsuite/23_containers/forward_list/version.cc: Likewise.
* testsuite/23_containers/list/version.cc: Likewise.
* testsuite/23_containers/map/version.cc: Likewise.
* testsuite/23_containers/set/version.cc: Likewise.
* testsuite/23_containers/unordered_map/version.cc: Likewise.
* testsuite/23_containers/unordered_set/version.cc: Likewise.
* testsuite/23_containers/vector/version.cc: Likewise.

(cherry picked from commit efe6efb6f315c7f97be8a850e0a84ff7f6651d85)

Diff:
---
 libstdc++-v3/include/std/deque| 1 +
 libstdc++-v3/include/std/forward_list | 1 +
 libstdc++-v3/include/std/list | 1 +
 libstdc++-v3/include/std/map  | 1 +
 libstdc++-v3/include/std/scoped_allocator | 3 +++
 libstdc++-v3/include/std/set  | 1 +
 libstdc++-v3/include/std/string   | 1 +
 libstdc++-v3/include/std/unordered_map| 1 +
 libstdc++-v3/include/std/unordered_set| 1 +
 libstdc++-v3/include/std/vector   | 1 +
 libstdc++-v3/testsuite/20_util/headers/memory/version.cc  | 8 
 libstdc++-v3/testsuite/20_util/scoped_allocator/version.cc| 8 
 libstdc++-v3/testsuite/21_strings/headers/string/version.cc   | 8 
 libstdc++-v3/testsuite/23_containers/deque/version.cc | 8 
 libstdc++-v3/testsuite/23_containers/forward_list/version.cc  | 8 
 libstdc++-v3/testsuite/23_containers/list/version.cc  | 8 
 libstdc++-v3/testsuite/23_containers/map/version.cc   | 8 
 libstdc++-v3/testsuite/23_containers/set/version.cc   | 8 
 libstdc++-v3/testsuite/23_containers/unordered_map/version.cc | 8 
 libstdc++-v3/testsuite/23_containers/unordered_set/version.cc | 8 
 libstdc++-v3/testsuite/23_containers/vector/version.cc| 8 
 21 files changed, 100 insertions(+)

diff --git a/libstdc++-v3/include/std/deque b/libstdc++-v3/include/std/deque
index 0bf8309c19a..69f8c0dcdcc 100644
--- a/libstdc++-v3/include/std/deque
+++ b/libstdc++-v3/include/std/deque
@@ -68,6 +68,7 @@
 #include 
 #include 
 
+#define __glibcxx_want_allocator_traits_is_always_equal
 #define __glibcxx_want_erase_if
 #define __glibcxx_want_nonmember_container_access
 #include 
diff --git a/libstdc++-v3/include/std/forward_list 
b/libstdc++-v3/include/std/forward_list
index 5ac74360808..dfd7d48d121 100644
--- a/libstdc++-v3/include/std/forward_list
+++ b/libstdc++-v3/include/std/forward_list
@@ -45,6 +45,7 @@
 # include 
 #endif
 
+#define __glibcxx_want_allocator_traits_is_always_equal
 #define __glibcxx_want_erase_if
 #define __glibcxx_want_incomplete_container_elements
 #define __glibcxx_want_list_remove_return_type
diff --git a/libstdc++-v3/include/std/list b/libstdc++-v3/include/std/list
index fce4e3d925b..ff632fc1ab2 100644
--- a/libstdc++-v3/include/std/list
+++ b/libstdc++-v3/include/std/list
@@ -69,6 +69,7 @@
 # include 
 #endif
 
+#define __glibcxx_want_allocator_traits_is_always_equal
 #define __glibcxx_want_erase_if
 #define __glibcxx_want_incomplete_container_elements
 #define __glibcxx_want_list_remove_return_type
diff --git a/libstdc++-v3/include/std/map b/libstdc++-v3/include/std/map
index 4a96e59a5bc..6520d9f744f 100644
--- a/libstdc++-v3/include/std/map
+++ b/libstdc++-v3/include/std/map
@@ -69,6 +69,7 @@
 # include 
 #endif
 
+#define __glibcxx_want_allocator_traits_is_always_equal
 #defin

[gcc r14-10636] libstdc++: Fix std::variant to reject array types [PR116381]

2024-09-04 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:3b8a67b0cfc072f027eab24fb72d48d10cc890b4

commit r14-10636-g3b8a67b0cfc072f027eab24fb72d48d10cc890b4
Author: Jonathan Wakely 
Date:   Tue Aug 20 16:52:22 2024 +0100

libstdc++: Fix std::variant to reject array types [PR116381]

For the backport, rejecting array types is only done in strict modes.

libstdc++-v3/ChangeLog:

PR libstdc++/116381
* include/std/variant (variant): Fix conditions for
static_assert to match the spec.
* testsuite/20_util/variant/types_neg.cc: New test.

(cherry picked from commit 1e10b3b8825ee398f077500af6ae1f5db180983a)

Diff:
---
 libstdc++-v3/include/std/variant| 11 +++
 libstdc++-v3/testsuite/20_util/variant/types_neg.cc | 18 ++
 2 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant
index 4e56134a6f7..834bb548f13 100644
--- a/libstdc++-v3/include/std/variant
+++ b/libstdc++-v3/include/std/variant
@@ -1374,10 +1374,13 @@ namespace __variant
 
   static_assert(sizeof...(_Types) > 0,
"variant must have at least one alternative");
-  static_assert(!(std::is_reference_v<_Types> || ...),
-   "variant must have no reference alternative");
-  static_assert(!(std::is_void_v<_Types> || ...),
-   "variant must have no void alternative");
+#ifdef __STRICT_ANSI__
+  static_assert(((std::is_object_v<_Types> && !is_array_v<_Types>) && ...),
+   "variant alternatives must be non-array object types");
+#else
+  static_assert((std::is_object_v<_Types> && ...),
+   "variant alternatives must be object types");
+#endif
 
   using _Base = __detail::__variant::_Variant_base<_Types...>;
 
diff --git a/libstdc++-v3/testsuite/20_util/variant/types_neg.cc 
b/libstdc++-v3/testsuite/20_util/variant/types_neg.cc
new file mode 100644
index 000..7d970e961c2
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/variant/types_neg.cc
@@ -0,0 +1,18 @@
+// { dg-do compile { target c++17 } }
+// { dg-add-options strict_std }
+
+# include 
+
+std::variant<> v0; // { dg-error "here" }
+// { dg-error "must have at least one alternative" "" { target *-*-* } 0 }
+std::variant v1; // { dg-error "here" }
+std::variant v2; // { dg-error "here" }
+std::variant v3; // { dg-error "here" }
+std::variant v4; // { dg-error "here" }
+std::variant v5; // { dg-error "here" }
+std::variant v6; // { dg-error "here" }
+// { dg-error "must be non-array object types" "" { target *-*-* } 0 }
+
+// All of variant's base classes are instantiated before checking any
+// static_assert, so we get lots of errors before the expected errors above.
+// { dg-excess-errors "" }


[gcc r15-3424] libstdc++: Fix error handling in fs::hard_link_count for Windows

2024-09-03 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:71b1639c67b91554420cc38eb4c82323e535c816

commit r15-3424-g71b1639c67b91554420cc38eb4c82323e535c816
Author: Jonathan Wakely 
Date:   Mon Sep 2 12:16:49 2024 +0100

libstdc++: Fix error handling in fs::hard_link_count for Windows

The recent change to use auto_win_file_handle for
std::filesystem::hard_link_count caused a regression. The
std::error_code argument should be cleared if no error occurs, but this
no longer happens. Add a call to ec.clear() in fs::hard_link_count to
fix this.

Also change the auto_win_file_handle class to take a reference to the
std::error_code and set it if an error occurs, to slightly simplify the
control flow in the fs::equiv_files function.

libstdc++-v3/ChangeLog:

* src/c++17/fs_ops.cc (auto_win_file_handle): Add error_code&
member and set it if CreateFileW or GetFileInformationByHandle
fails.
(fs::equiv_files) [_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Simplify
control flow.
(fs::hard_link_count) [_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Clear ec
on success.
* testsuite/27_io/filesystem/operations/hard_link_count.cc:
Check error handling.

Diff:
---
 libstdc++-v3/src/c++17/fs_ops.cc   | 59 --
 .../27_io/filesystem/operations/hard_link_count.cc | 24 +
 2 files changed, 57 insertions(+), 26 deletions(-)

diff --git a/libstdc++-v3/src/c++17/fs_ops.cc b/libstdc++-v3/src/c++17/fs_ops.cc
index 9606afa9f1f7..946fefd9e449 100644
--- a/libstdc++-v3/src/c++17/fs_ops.cc
+++ b/libstdc++-v3/src/c++17/fs_ops.cc
@@ -829,23 +829,37 @@ namespace
   struct auto_win_file_handle
   {
 explicit
-auto_win_file_handle(const wchar_t* p)
+auto_win_file_handle(const wchar_t* p, std::error_code& ec) noexcept
 : handle(CreateFileW(p, 0,
 FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
-0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0))
-{ }
+0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)),
+  ec(ec)
+{
+  if (handle == INVALID_HANDLE_VALUE)
+   ec = std::__last_system_error();
+}
 
 ~auto_win_file_handle()
 { if (*this) CloseHandle(handle); }
 
-explicit operator bool() const
+explicit operator bool() const noexcept
 { return handle != INVALID_HANDLE_VALUE; }
 
-bool get_info()
-{ return GetFileInformationByHandle(handle, &info); }
+bool get_info() noexcept
+{
+  if (GetFileInformationByHandle(handle, &info))
+   return true;
+  ec = std::__last_system_error();
+  return false;
+}
 
 HANDLE handle;
 BY_HANDLE_FILE_INFORMATION info;
+// Like errno, we only set this on error and never clear it.
+// This propagates an error_code to the caller when something goes wrong,
+// but the caller should not assume a non-zero ec means an error happened
+// unless they explicitly cleared it before passing it to our constructor.
+std::error_code& ec;
   };
 }
 #endif
@@ -866,23 +880,14 @@ fs::equiv_files([[maybe_unused]] const char_type* p1, 
const stat_type& st1,
   if (st1.st_mode != st2.st_mode || st1.st_dev != st2.st_dev)
 return false;
 
-  // Need to use GetFileInformationByHandle to get more info about the files.
-  auto_win_file_handle h1(p1);
-  auto_win_file_handle h2(p2);
-  if (!h1 || !h2)
-{
-  if (!h1 && !h2)
-   ec = __last_system_error();
-  return false;
-}
-  if (!h1.get_info() || !h2.get_info())
-{
-  ec = __last_system_error();
-  return false;
-}
-  return h1.info.dwVolumeSerialNumber == h2.info.dwVolumeSerialNumber
-  && h1.info.nFileIndexHigh == h2.info.nFileIndexHigh
-  && h1.info.nFileIndexLow == h2.info.nFileIndexLow;
+  // Use GetFileInformationByHandle to get more info about the files.
+  if (auto_win_file_handle h1{p1, ec})
+if (auto_win_file_handle h2{p2, ec})
+  if (h1.get_info() && h2.get_info())
+   return h1.info.dwVolumeSerialNumber == h2.info.dwVolumeSerialNumber
+&& h1.info.nFileIndexHigh == h2.info.nFileIndexHigh
+&& h1.info.nFileIndexLow == h2.info.nFileIndexLow;
+  return false;
 #endif // _GLIBCXX_FILESYSTEM_IS_WINDOWS
 }
 #endif // NEED_DO_COPY_FILE
@@ -1007,10 +1012,12 @@ std::uintmax_t
 fs::hard_link_count(const path& p, error_code& ec) noexcept
 {
 #if _GLIBCXX_FILESYSTEM_IS_WINDOWS
-  auto_win_file_handle h(p.c_str());
+  auto_win_file_handle h(p.c_str(), ec);
   if (h && h.get_info())
-return static_cast(h.info.nNumberOfLinks);
-  ec = __last_system_error();
+{
+  ec.clear();
+  return static_cast(h.info.nNumberOfLinks);
+}
   return static_cast(-1);
 #elif defined _GLIBCXX_HAVE_SYS_STAT_H
   return do_stat(p, ec, std::mem_fn(&stat_type::st_nlink),
diff --git 
a/libstdc++-v3/testsuite/27_io/filesystem/operations/hard_link_count.cc 
b/libstdc+

[gcc r15-3423] libstdc++: Specialize std::disable_sized_sentinel_for for std::move_iterator [PR116549]

2024-09-03 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:819deae0a5bee079a7d5582fafaa098c26144ae8

commit r15-3423-g819deae0a5bee079a7d5582fafaa098c26144ae8
Author: Jonathan Wakely 
Date:   Mon Sep 2 11:29:13 2024 +0100

libstdc++: Specialize std::disable_sized_sentinel_for for 
std::move_iterator [PR116549]

LWG 3736 added a partial specialization of this variable template for
two std::move_iterator types. This is needed for the case where the
types satisfy std::sentinel_for and are subtractable, but do not model
the semantics requirements of std::sized_sentinel_for.

libstdc++-v3/ChangeLog:

PR libstdc++/116549
* include/bits/stl_iterator.h (disable_sized_sentinel_for):
Define specialization for two move_iterator types, as per LWG
3736.
* testsuite/24_iterators/move_iterator/lwg3736.cc: New test.

Diff:
---
 libstdc++-v3/include/bits/stl_iterator.h   |  8 
 .../24_iterators/move_iterator/lwg3736.cc  | 52 ++
 2 files changed, 60 insertions(+)

diff --git a/libstdc++-v3/include/bits/stl_iterator.h 
b/libstdc++-v3/include/bits/stl_iterator.h
index d38230572709..20c0319f3a7a 100644
--- a/libstdc++-v3/include/bits/stl_iterator.h
+++ b/libstdc++-v3/include/bits/stl_iterator.h
@@ -1822,6 +1822,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { return _ReturnType(__i); }
 
 #if __cplusplus > 201703L && __glibcxx_concepts
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // 3736.  move_iterator missing disable_sized_sentinel_for specialization
+  template
+requires (!sized_sentinel_for<_Iterator1, _Iterator2>)
+inline constexpr bool
+disable_sized_sentinel_for,
+  move_iterator<_Iterator2>> = true;
+
   // [iterators.common] Common iterators
 
   namespace __detail
diff --git a/libstdc++-v3/testsuite/24_iterators/move_iterator/lwg3736.cc 
b/libstdc++-v3/testsuite/24_iterators/move_iterator/lwg3736.cc
new file mode 100644
index ..eaf791b30893
--- /dev/null
+++ b/libstdc++-v3/testsuite/24_iterators/move_iterator/lwg3736.cc
@@ -0,0 +1,52 @@
+// { dg-do compile { target c++20 } }
+
+// 3736.  move_iterator missing disable_sized_sentinel_for specialization
+
+#include 
+
+template using MoveIter = std::move_iterator;
+
+using std::sized_sentinel_for;
+using std::disable_sized_sentinel_for;
+
+// These assertions always passed, even without LWG 3736:
+static_assert(sized_sentinel_for, MoveIter>);
+static_assert(sized_sentinel_for, MoveIter>);
+static_assert(not sized_sentinel_for, MoveIter>);
+static_assert(not sized_sentinel_for, std::default_sentinel_t>);
+static_assert(not disable_sized_sentinel_for, MoveIter>);
+
+// These types don't satisfy sized_sentinel_for anyway (because the subtraction
+// is ill-formed) but LWG 3736 makes the variable template explicitly false:
+static_assert(disable_sized_sentinel_for, MoveIter>);
+
+struct Iter
+{
+  using iterator_category = std::random_access_iterator_tag;
+  using value_type = int;
+  using pointer = int*;
+  using reference = int&;
+  using difference_type = long;
+
+  Iter() = default;
+  Iter& operator++();
+  Iter operator++(int);
+  Iter& operator--();
+  Iter operator--(int);
+  reference operator*() const;
+  pointer operator->() const;
+  Iter& operator+=(difference_type);
+  Iter& operator-=(difference_type);
+  friend Iter operator+(Iter, difference_type);
+  friend Iter operator+(difference_type, Iter);
+  friend Iter operator-(Iter, difference_type);
+  friend difference_type operator-(Iter, Iter);
+  bool operator==(Iter) const;
+};
+
+// Specialize the variable template so that Iter is not its own sized sentinel:
+template<> constexpr bool std::disable_sized_sentinel_for = true;
+static_assert( not sized_sentinel_for );
+
+// LWG 3736 means that affects std::move_iterator as well:
+static_assert( not sized_sentinel_for, MoveIter> );


[gcc r15-3418] libstdc++: Add missing feature-test macro in various headers

2024-09-03 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:efe6efb6f315c7f97be8a850e0a84ff7f6651d85

commit r15-3418-gefe6efb6f315c7f97be8a850e0a84ff7f6651d85
Author: Dhruv Chawla 
Date:   Mon Aug 26 11:09:19 2024 +0530

libstdc++: Add missing feature-test macro in various headers

version.syn#2 requires various headers to define
__cpp_lib_allocator_traits_is_always_equal. Currently, only  was
defining this macro. Implement fixes for the other headers as well.

Signed-off-by: Dhruv Chawla 

libstdc++-v3/ChangeLog:

* include/std/deque: Define macro
__glibcxx_want_allocator_traits_is_always_equal.
* include/std/forward_list: Likewise.
* include/std/list: Likewise.
* include/std/map: Likewise.
* include/std/scoped_allocator: Likewise.
* include/std/set: Likewise.
* include/std/string: Likewise.
* include/std/unordered_map: Likewise.
* include/std/unordered_set: Likewise.
* include/std/vector: Likewise.
* testsuite/20_util/headers/memory/version.cc: New test.
* testsuite/20_util/scoped_allocator/version.cc: Likewise.
* testsuite/21_strings/headers/string/version.cc: Likewise.
* testsuite/23_containers/deque/version.cc: Likewise.
* testsuite/23_containers/forward_list/version.cc: Likewise.
* testsuite/23_containers/list/version.cc: Likewise.
* testsuite/23_containers/map/version.cc: Likewise.
* testsuite/23_containers/set/version.cc: Likewise.
* testsuite/23_containers/unordered_map/version.cc: Likewise.
* testsuite/23_containers/unordered_set/version.cc: Likewise.
* testsuite/23_containers/vector/version.cc: Likewise.

Diff:
---
 libstdc++-v3/include/std/deque| 1 +
 libstdc++-v3/include/std/forward_list | 1 +
 libstdc++-v3/include/std/list | 1 +
 libstdc++-v3/include/std/map  | 1 +
 libstdc++-v3/include/std/scoped_allocator | 3 +++
 libstdc++-v3/include/std/set  | 1 +
 libstdc++-v3/include/std/string   | 1 +
 libstdc++-v3/include/std/unordered_map| 1 +
 libstdc++-v3/include/std/unordered_set| 1 +
 libstdc++-v3/include/std/vector   | 1 +
 libstdc++-v3/testsuite/20_util/headers/memory/version.cc  | 8 
 libstdc++-v3/testsuite/20_util/scoped_allocator/version.cc| 8 
 libstdc++-v3/testsuite/21_strings/headers/string/version.cc   | 8 
 libstdc++-v3/testsuite/23_containers/deque/version.cc | 8 
 libstdc++-v3/testsuite/23_containers/forward_list/version.cc  | 8 
 libstdc++-v3/testsuite/23_containers/list/version.cc  | 8 
 libstdc++-v3/testsuite/23_containers/map/version.cc   | 8 
 libstdc++-v3/testsuite/23_containers/set/version.cc   | 8 
 libstdc++-v3/testsuite/23_containers/unordered_map/version.cc | 8 
 libstdc++-v3/testsuite/23_containers/unordered_set/version.cc | 8 
 libstdc++-v3/testsuite/23_containers/vector/version.cc| 8 
 21 files changed, 100 insertions(+)

diff --git a/libstdc++-v3/include/std/deque b/libstdc++-v3/include/std/deque
index 0bf8309c19a7..69f8c0dcdccf 100644
--- a/libstdc++-v3/include/std/deque
+++ b/libstdc++-v3/include/std/deque
@@ -68,6 +68,7 @@
 #include 
 #include 
 
+#define __glibcxx_want_allocator_traits_is_always_equal
 #define __glibcxx_want_erase_if
 #define __glibcxx_want_nonmember_container_access
 #include 
diff --git a/libstdc++-v3/include/std/forward_list 
b/libstdc++-v3/include/std/forward_list
index 5ac74360808d..dfd7d48d1219 100644
--- a/libstdc++-v3/include/std/forward_list
+++ b/libstdc++-v3/include/std/forward_list
@@ -45,6 +45,7 @@
 # include 
 #endif
 
+#define __glibcxx_want_allocator_traits_is_always_equal
 #define __glibcxx_want_erase_if
 #define __glibcxx_want_incomplete_container_elements
 #define __glibcxx_want_list_remove_return_type
diff --git a/libstdc++-v3/include/std/list b/libstdc++-v3/include/std/list
index fce4e3d925b1..ff632fc1ab2f 100644
--- a/libstdc++-v3/include/std/list
+++ b/libstdc++-v3/include/std/list
@@ -69,6 +69,7 @@
 # include 
 #endif
 
+#define __glibcxx_want_allocator_traits_is_always_equal
 #define __glibcxx_want_erase_if
 #define __glibcxx_want_incomplete_container_elements
 #define __glibcxx_want_list_remove_return_type
diff --git a/libstdc++-v3/include/std/map b/libstdc++-v3/include/std/map
index 4a96e59a5bc1..6520d9f744fe 100644
--- a/libstdc++-v3/include/std/map
+++ b/libstdc++-v3/include/std/map
@@ -69,6 +69,7 @@
 # include 
 #endif
 
+#define __glibcxx_want_allocator_traits_is_always_equal
 #define __glibcxx_want_erase_if
 #define __glibcxx_want_generic_associative_l

[gcc r15-3267] doc: Add Dhruv Matani to Contributors

2024-08-28 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:9740a1b0dc10c93f325fb17dacea7d123bc0cdd2

commit r15-3267-g9740a1b0dc10c93f325fb17dacea7d123bc0cdd2
Author: Jonathan Wakely 
Date:   Wed Aug 28 11:49:46 2024 +0100

doc: Add Dhruv Matani to Contributors

gcc/ChangeLog:

* doc/contrib.texi (Contributors): Add Dhruv Matani.

Diff:
---
 gcc/doc/contrib.texi | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/gcc/doc/contrib.texi b/gcc/doc/contrib.texi
index 32e89d6df25c..7714d52823b1 100644
--- a/gcc/doc/contrib.texi
+++ b/gcc/doc/contrib.texi
@@ -645,6 +645,9 @@ John Marino for contributing the DragonFly BSD port.
 Philip Martin for lots of libstdc++ string and vector iterator fixes and
 improvements, and string clean up and testsuites.
 
+@item
+Dhruv Matani for work on libstdc++ allocators.
+
 @item
 Michael Matz for his work on dominance tree discovery, the x86-64 port,
 link-time optimization framework and general optimization improvements.


[gcc r15-3265] libstdc++: Fix @headername for bits/cpp_type_traits.h

2024-08-28 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:f6ed7a61a7c906f8fb7f8059132225c9bc41f3b2

commit r15-3265-gf6ed7a61a7c906f8fb7f8059132225c9bc41f3b2
Author: Kim Gräsman 
Date:   Tue Aug 27 17:08:47 2024 +0100

libstdc++: Fix @headername for bits/cpp_type_traits.h

There is no file ext/type_traits, point it to ext/type_traits.h instead.

libstdc++-v3/ChangeLog:

* include/bits/cpp_type_traits.h: Improve doxygen file docs.

Diff:
---
 libstdc++-v3/include/bits/cpp_type_traits.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/bits/cpp_type_traits.h 
b/libstdc++-v3/include/bits/cpp_type_traits.h
index 4bfb4521e064..ff74c5572458 100644
--- a/libstdc++-v3/include/bits/cpp_type_traits.h
+++ b/libstdc++-v3/include/bits/cpp_type_traits.h
@@ -24,7 +24,7 @@
 
 /** @file bits/cpp_type_traits.h
  *  This is an internal header file, included by other library headers.
- *  Do not attempt to use it directly. @headername{ext/type_traits}
+ *  Do not attempt to use it directly. @headername{ext/type_traits.h}
  */
 
 // Written by Gabriel Dos Reis 


[gcc r15-3217] c++: Add most missing C++20 and C++23 names to cxxapi-data.csv

2024-08-27 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:470a27859d8a47a99f389f1dc6edb82c08b16e21

commit r15-3217-g470a27859d8a47a99f389f1dc6edb82c08b16e21
Author: Jonathan Wakely 
Date:   Tue Aug 27 12:19:47 2024 +0100

c++: Add most missing C++20 and C++23 names to cxxapi-data.csv

This includes uncommenting the atomic_flag non-member functions, which
were added by PR libstdc++/103934.

Also generate a hint for std::ignore, which was recently tweaked to be
more generally useful by P2968R2, which r15-2324 implemented.

gcc/cp/ChangeLog:

* cxxapi-data.csv: Add C++20 and C++23 names from ,
, , , , and .
Set cxx11 dialect for std::ignore in . Uncomment
atomic_flag functions from .
* std-name-hint.gperf: Regenerate.
* std-name-hint.h: Regenerate.

Diff:
---
 gcc/cp/cxxapi-data.csv |   96 ++-
 gcc/cp/std-name-hint.gperf |   82 ++
 gcc/cp/std-name-hint.h | 2029 
 3 files changed, 1295 insertions(+), 912 deletions(-)

diff --git a/gcc/cp/cxxapi-data.csv b/gcc/cp/cxxapi-data.csv
index 1cbf774acd7c..bd397fb2acb8 100644
--- a/gcc/cp/cxxapi-data.csv
+++ b/gcc/cp/cxxapi-data.csv
@@ -197,16 +197,16 @@
 ,atomic_uintmax_t,1,cxx20
 
,atomic_signed_lock_free,1,cxx11,__cpp_lib_atomic_lock_free_type_aliases
 
,atomic_unsigned_lock_free,1,cxx11,__cpp_lib_atomic_lock_free_type_aliases
-# libstdc++/103934 ,atomic_flag_test,1,no
-# libstdc++/103934 ,atomic_flag_test_explicit,1,no
+,atomic_flag_test,1,no
+,atomic_flag_test_explicit,1,no
 ,atomic_flag_test_and_set,1,no
 ,atomic_flag_test_and_set_explicit,1,no
 ,atomic_flag_clear,1,no
 ,atomic_flag_clear_explicit,1,no
-# libstdc++/103934 ,atomic_flag_wait,1,no
-# libstdc++/103934 ,atomic_flag_wait_explicit,1,no
-# libstdc++/103934 ,atomic_flag_notify_one,1,no
-# libstdc++/103934 ,atomic_flag_notify_all,1,no
+,atomic_flag_wait,1,no
+,atomic_flag_wait_explicit,1,no
+,atomic_flag_notify_one,1,no
+,atomic_flag_notify_all,1,no
 ,atomic_thread_fence,1,no
 ,atomic_signal_fence,1,no
 ,barrier,1,no
@@ -238,7 +238,48 @@
 ,to_chars,1,no
 ,from_chars_result,1,no
 ,from_chars,1,no
-#  TODO
+,chrono::duration,1,cxx11
+,chrono::nanoseconds,1,cxx11
+,chrono::microseconds,1,cxx11
+,chrono::milliseconds,1,cxx11
+,chrono::seconds,1,cxx11
+,chrono::minutes,1,cxx11
+,chrono::hours,1,cxx11
+,chrono::days,1,cxx20
+,chrono::weeks,1,cxx20
+,chrono::months,1,cxx20
+,chrono::years,1,cxx20
+,chrono::duration_cast,1,cxx11
+,chrono::time_point,1,cxx11
+,chrono::time_point_cast,1,cxx11
+,chrono::system_clock,1,cxx11
+,chrono::steady_clock,1,cxx11
+,chrono::high_resolution_clock,1,cxx11
+,chrono::utc_clock,1,cxx20
+,chrono::tai_clock,1,cxx20
+,chrono::gps_clock,1,cxx20
+,chrono::file_clock,1,cxx20
+,chrono::local_t,1,cxx20
+,chrono::clock_cast,1,cxx20
+,chrono::time_zone,1,cxx20
+,chrono::zoned_time,1,cxx20
+,chrono::tzdb,1,cxx20
+,chrono::tzdb_list,1,cxx20
+,chrono::get_tzdb,1,cxx20
+,chrono::get_tzdb_list,1,cxx20
+,chrono::reload_tzdb,1,cxx20
+,chrono::remote_version,1,cxx20
+,chrono::locate_zone,1,cxx20
+,chrono::leap_second,1,cxx20
+,chrono::leap_second_info,1,cxx20
+,chrono::get_leap_second_info,1,cxx20
+# c++/106851 ,chrono::abs,1,cxx17
+# c++/106851 ,chrono::floor,1,cxx17
+# c++/106851 ,chrono::ceil,1,cxx17
+,chrono::round,1,cxx17
+,chrono::from_stream,1,cxx20
+,chrono::parse,1,cxx20
+#  TODO the rest
 #  TODO
 ,weak_equality,1,cxx20
 ,strong_equality,1,cxx20
@@ -311,6 +352,33 @@
 # ,sorted_equivalent,1,no
 # ,erase_if,1,no
 # ,uses_allocator,1,no
+,format,1,cxx20
+,format_to,1,cxx20
+,format_to_n,1,cxx20
+,formatted_size,1,cxx20
+,vformat,1,cxx20
+,vformat_to,1,cxx20
+,formatter,1,cxx20
+,range_formatter,1,cxx23
+,range_format,1,cxx23
+,formattable,1,cxx23
+,format_error,1,cxx20
+,basic_format_parse_context,1,cxx20
+,format_parse_context,1,cxx20
+,wformat_parse_context,1,cxx20
+,basic_format_context,1,cxx20
+,format_context,1,cxx20
+,wformat_context,1,cxx20
+,basic_format_string,1,cxx20
+,format_string,1,cxx20
+,wformat_string,1,cxx20
+,basic_format_arg,1,cxx20
+,basic_format_args,1,cxx20
+,format_args,1,cxx20
+,wformat_args,1,cxx20
+,make_format_args,1,cxx20
+,make_wformat_args,1,cxx20
+,runtime_format,1,cxx26
 ,forward_list,1,cxx11
 ,operator==,1,no
 ,operator<=>,1,no
@@ -361,6 +429,8 @@
 ,shared_future,1,no
 ,packaged_task,1,cxx11
 ,async,1,cxx11
+,generator,1,cxx23
+# c++/106851 ,pmr::generator,1,no
 ,initializer_list,1,no
 ,begin,1,no
 ,end,1,no
@@ -433,6 +503,9 @@
 ,ostreambuf_iterator,1,cxx98
 ,prev,1,cxx11
 ,reverse_iterator,1,cxx98
+,common_iterator,1,cxx20
+,counted_iterator,1,cxx20
+,const_iterator,1,cxx23
 #  TODO the rest
 ,latch,1,no
 ,list,1,cxx98
@@ -590,6 +663,8 @@
 ,flush_emit,1,cxx20
 ,operator<<,1,no
 #  TODO
+,print,1,cxx23
+,println,1,cxx23
 ,queue,1,cxx98
 ,operator==,1,no
 ,operator!=,1,no
@@ -720,6 +795,11 @@
 ,range_error,1,cxx98
 ,overflow_error,1,cxx98
 ,underflow_error,1,cxx98
+,float16_t,1,cxx23
+,float32_t,1,cxx23
+,float64_t,1,cxx23
+,float128_

[gcc r15-3216] c++: Add correct copyright dates to output of gen-cxxapi-file.py

2024-08-27 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:ff4aa45535bc0103e4417e72386089a5421fe520

commit r15-3216-gff4aa45535bc0103e4417e72386089a5421fe520
Author: Jonathan Wakely 
Date:   Tue Aug 27 12:17:03 2024 +0100

c++: Add correct copyright dates to output of gen-cxxapi-file.py

This ensures the generated output says something like 2022-2024 rather
than just 2024.

gcc/cp/ChangeLog:

* gen-cxxapi-file.py: Fix copyright dates in generated output.

Diff:
---
 gcc/cp/gen-cxxapi-file.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/cp/gen-cxxapi-file.py b/gcc/cp/gen-cxxapi-file.py
index 31ed5b16ce45..6d08f46069bb 100644
--- a/gcc/cp/gen-cxxapi-file.py
+++ b/gcc/cp/gen-cxxapi-file.py
@@ -95,7 +95,7 @@ def hints(script, content):
 %struct-type
 %{{
 /* This file is auto-generated by {:s}.  */
-/* Copyright (C) {:s} Free Software Foundation, Inc.
+/* Copyright (C) 2022-{:s} Free Software Foundation, Inc.
 
 This file is part of GCC.


[gcc r15-3141] libstdc++: Hide std::tuple internals from Doxygen docs

2024-08-23 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:5cfee9360c90da8171e9f6bb71568bdc4c296e6e

commit r15-3141-g5cfee9360c90da8171e9f6bb71568bdc4c296e6e
Author: Jonathan Wakely 
Date:   Fri Aug 23 22:06:43 2024 +0100

libstdc++: Hide std::tuple internals from Doxygen docs

libstdc++-v3/ChangeLog:

* include/std/tuple: Do not include implementation details in
Doxygen documentation.

Diff:
---
 libstdc++-v3/include/std/tuple | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index 93b649e7d211..70cf4dba7b93 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -66,6 +66,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 class tuple;
 
+  /// @cond undocumented
   template
 struct __is_empty_non_tuple : is_empty<_Tp> { };
 
@@ -823,6 +824,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static constexpr bool __is_explicitly_constructible()
{ return false; }
 };
+  /// @endcond
 
   /// Primary class template, tuple
   template


[gcc r15-3134] libstdc++: Implement LWG 3746 for std::optional

2024-08-23 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:c429d509a86d61b21298b787948e24a9c97084e3

commit r15-3134-gc429d509a86d61b21298b787948e24a9c97084e3
Author: Jonathan Wakely 
Date:   Tue Jun 25 21:58:34 2024 +0100

libstdc++: Implement LWG 3746 for std::optional

This avoids constraint recursion in operator<=> for std::optional.
The resolution was approved in Kona 2022.

libstdc++-v3/ChangeLog:

* include/std/optional (__is_derived_from_optional): New
concept.
(operator<=>): Use __is_derived_from_optional.
* testsuite/20_util/optional/relops/lwg3746.cc: New test.

Diff:
---
 libstdc++-v3/include/std/optional| 12 ++--
 .../testsuite/20_util/optional/relops/lwg3746.cc | 20 
 2 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/std/optional 
b/libstdc++-v3/include/std/optional
index 6651686cd1d0..933a5b15e569 100644
--- a/libstdc++-v3/include/std/optional
+++ b/libstdc++-v3/include/std/optional
@@ -1581,9 +1581,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { return !__rhs; }
 #endif // three-way-comparison
 
+#if __cpp_lib_concepts
   // _GLIBCXX_RESOLVE_LIB_DEFECTS
   // 4072. std::optional comparisons: constrain harder
-#if __cpp_lib_concepts
 # define _REQUIRES_NOT_OPTIONAL(T) requires (!__is_optional_v)
 #else
 # define _REQUIRES_NOT_OPTIONAL(T)
@@ -1675,8 +1675,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 { return !__rhs || __lhs >= *__rhs; }
 
 #ifdef __cpp_lib_three_way_comparison
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // 3746. optional's spaceship with U with a type derived from optional
+  // causes infinite constraint meta-recursion
+  template
+concept __is_derived_from_optional = requires (const _Tp& __t) {
+  [](const optional<_Up>&){ }(__t);
+};
+
   template
-requires (!__is_optional_v<_Up>)
+requires (!__is_derived_from_optional<_Up>)
   && three_way_comparable_with<_Up, _Tp>
 constexpr compare_three_way_result_t<_Tp, _Up>
 operator<=> [[nodiscard]] (const optional<_Tp>& __x, const _Up& __v)
diff --git a/libstdc++-v3/testsuite/20_util/optional/relops/lwg3746.cc 
b/libstdc++-v3/testsuite/20_util/optional/relops/lwg3746.cc
new file mode 100644
index ..46065f8e901d
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/optional/relops/lwg3746.cc
@@ -0,0 +1,20 @@
+// { dg-do compile { target c++20 } }
+
+// LWG 3746. optional's spaceship with U with a type derived from optional
+// causes infinite constraint meta-recursion
+
+#include 
+
+struct S : std::optional
+{
+bool operator==(const S&) const;
+bool operator<(const S&) const;
+bool operator>(const S&) const;
+bool operator<=(const S&) const;
+bool operator>=(const S&) const;
+};
+
+auto cmp(const S& s, const std::optional& o)
+{
+  return s <=> o;
+}


[gcc r15-3131] libstdc++: Only use std::time_put in std::format for non-C locales

2024-08-23 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:43b8153c26655a7a00f1584fcb4f511dc5e45fab

commit r15-3131-g43b8153c26655a7a00f1584fcb4f511dc5e45fab
Author: Jonathan Wakely 
Date:   Wed Jul 31 16:32:44 2024 +0100

libstdc++: Only use std::time_put in std::format for non-C locales

When testing on Solaris I noticed that std/time/year/io.cc was FAILing
because the year 1642 was being formatted as "+(" by %Ey. This turns out
to be because we defer to std::time_put for modified conversion specs,
and std::time_put uses std::strftime, and that's undefined for years
before 1970. In particular, years before 1900 mean that the tm_year
field is negative, which then causes incorrect results from strftime on
at least Solaris and AIX.

I've raised the general problem with LWG, but we can fix the FAILing
test case (and probably improve performance slightly) by ignoring the E
and O modifiers when the formatting locale is the "C" locale. The
modifiers have no effect for the C locale, so we can just treat %Ey as
%y and format it directly. This doesn't fix anything when the formatting
locale isn't the C locale, but that case is not adequately tested, so
doesn't cause any FAIL right now!

The naïve fix would be simply:

  if (__mod)
if (auto __loc = _M_locale(__ctx); __loc != locale::classic())
  // ...

However when the format string doesn't use the 'L' option, _M_locale
always returns locale::classic(). In that case, we make a copy of the
classic locale (which calls the non-inline copy constructor in
the library), then make another copy of the classic locale, then compare
the two. We can avoid all that by checking for the 'L' option first,
instead of letting _M_locale do that:

  if (__mod && _M_spec._M_localized)
if (auto __loc = __ctx.locale(); __loc != locale::classic())
  // ...

We could optimize this further if we had a __is_classic(__loc) function
that would do the __loc == locale::classic() check without making any
copies or non-inline calls. That would require examining the locale's
_M_impl member, and probably require checking its name, because the
locale::_S_classic singleton is not exported from the library.

For _M_S the change is slightly different from the other functions,
because if we skip using std::time_put for %OS then we fall through to
the code that potentially prints fractional seconds, but the %OS format
only prints whole seconds. So we need to format whole seconds directly
when not using std::time_put, instead of falling through to the code
below.

libstdc++-v3/ChangeLog:

* include/bits/chrono_io.h (__formatter_chrono::_M_C_y_Y):
Ignore modifiers unless the formatting locale is not the C
locale.
(__formatter_chrono::_M_d_e): Likewise.
(__formatter_chrono::_M_H_I): Likewise.
(__formatter_chrono::_M_m): Likewise.
(__formatter_chrono::_M_M): Likewise.
(__formatter_chrono::_M_S): Likewise.
(__formatter_chrono::_M_u_w): Likewise.
(__formatter_chrono::_M_U_V_W): Likewise.

Diff:
---
 libstdc++-v3/include/bits/chrono_io.h | 133 +++---
 1 file changed, 74 insertions(+), 59 deletions(-)

diff --git a/libstdc++-v3/include/bits/chrono_io.h 
b/libstdc++-v3/include/bits/chrono_io.h
index a449ffdc5583..38a0b002c81c 100644
--- a/libstdc++-v3/include/bits/chrono_io.h
+++ b/libstdc++-v3/include/bits/chrono_io.h
@@ -917,13 +917,14 @@ namespace __format
 
  chrono::year __y = _S_year(__t);
 
- if (__mod) [[unlikely]]
-   {
- struct tm __tm{};
- __tm.tm_year = (int)__y - 1900;
- return _M_locale_fmt(std::move(__out), _M_locale(__ctx), __tm,
-  __conv, __mod);
-   }
+ if (__mod && _M_spec._M_localized) [[unlikely]]
+   if (auto __loc = __ctx.locale(); __loc != locale::classic())
+ {
+   struct tm __tm{};
+   __tm.tm_year = (int)__y - 1900;
+   return _M_locale_fmt(std::move(__out), __loc, __tm,
+__conv, __mod);
+ }
 
  basic_string<_CharT> __s;
  int __yi = (int)__y;
@@ -985,13 +986,14 @@ namespace __format
  chrono::day __d = _S_day(__t);
  unsigned __i = (unsigned)__d;
 
- if (__mod) [[unlikely]]
-   {
- struct tm __tm{};
- __tm.tm_mday = __i;
- return _M_locale_fmt(std::move(__out), _M_locale(__ctx), __tm,
-  (char)__conv, 'O');
-   }
+ if (__mod && _M_spec._M_localized) [[unlikely]]
+   if (auto __loc = __ctx.locale(); __loc != locale::classic())
+ {
+   struct tm __tm{};
+   __tm.tm_mday = __i;
+  

[gcc r15-3132] libstdc++: Fix std::allocator_traits::construct constraints [PR108619]

2024-08-23 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:8cf51d7516b92b352c358c14ab4e456ae53c3371

commit r15-3132-g8cf51d7516b92b352c358c14ab4e456ae53c3371
Author: Jonathan Wakely 
Date:   Wed Jul 10 23:14:19 2024 +0100

libstdc++: Fix std::allocator_traits::construct constraints [PR108619]

Using std::is_constructible in the constraints introduces a spurious
dependency on the type being destructible, which should not be required
for constructing with an allocator. The test case shows a case where the
type has a private destructor, which can be destroyed by the allocator,
but std::is_destructible and std::is_constructible are false.

Similarly, using is_nothrow_constructible in the noexcept-specifiers
for the construct members of allocator_traits and std::allocator,
__gnu_cxx::__new_allocator, and __gnu_cxx::__malloc_allocator gives the
wrong answer if the type isn't destructible.
We need a new type trait to define those correctly, so that we only
check if the placement new-expression is nothrow after using
is_constructible to check that it would be well-formed.

Instead of just fixing the overly restrictive constraint to check for
placement new, rewrite allocator_traits in terms of 'if constexpr' using
variable templates and the detection idiom.

Although we can use 'if constexpr' and variable templates in C++11 with
appropriate uses of diagnostic pragmas, we can't have constexpr
functions with multiple return statements. This means that in C++11 mode
the _S_nothrow_construct and _S_nothrow_destroy helpers used for
noexcept-specifiers still need to be overlaods using enable_if. Nearly
everything else can be simplified to reduce overload resolution and
enable_if checks.

libstdc++-v3/ChangeLog:

PR libstdc++/108619
* include/bits/alloc_traits.h (__allocator_traits_base): Add
variable templates for detecting which allocator operations are
supported.
(allocator_traits): Use 'if constexpr' instead of dispatching to
overloads constrained with enable_if.
(allocator_traits>::construct): Use Construct if
construct_at is not supported. Use
__is_nothrow_new_constructible for noexcept-specifier.
(allocator_traits>::construct): Use
__is_nothrow_new_constructible for noexcept-specifier.
* include/bits/new_allocator.h (construct): Likewise.
* include/ext/malloc_allocator.h (construct): Likewise.
* include/std/type_traits (__is_nothrow_new_constructible): New
variable template.
* testsuite/20_util/allocator/89510.cc: Adjust expected results.
* testsuite/ext/malloc_allocator/89510.cc: Likewise.
* testsuite/ext/new_allocator/89510.cc: Likewise.
* testsuite/20_util/allocator_traits/members/108619.cc: New test.

Diff:
---
 libstdc++-v3/include/bits/alloc_traits.h   | 351 ++---
 libstdc++-v3/include/bits/new_allocator.h  |   2 +-
 libstdc++-v3/include/ext/malloc_allocator.h|   2 +-
 libstdc++-v3/include/std/type_traits   |  15 +
 libstdc++-v3/testsuite/20_util/allocator/89510.cc  |  14 +-
 .../20_util/allocator_traits/members/108619.cc |  35 ++
 .../testsuite/ext/malloc_allocator/89510.cc|  14 +-
 libstdc++-v3/testsuite/ext/new_allocator/89510.cc  |  14 +-
 8 files changed, 314 insertions(+), 133 deletions(-)

diff --git a/libstdc++-v3/include/bits/alloc_traits.h 
b/libstdc++-v3/include/bits/alloc_traits.h
index 82fc79c7b9f9..c2acc2ab2070 100644
--- a/libstdc++-v3/include/bits/alloc_traits.h
+++ b/libstdc++-v3/include/bits/alloc_traits.h
@@ -48,10 +48,19 @@ namespace std _GLIBCXX_VISIBILITY(default)
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 #if __cplusplus >= 201103L
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wc++14-extensions" // for variable templates
+#pragma GCC diagnostic ignored "-Wc++17-extensions" // for if-constexpr
+
   /// @cond undocumented
   struct __allocator_traits_base
   {
+#if __cpp_concepts
+template
+#else
 template
+#endif
   struct __rebind : __replace_first_arg<_Tp, _Up>
   {
static_assert(is_same<
@@ -61,8 +70,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   };
 
 template
+#if __cpp_concepts
+  requires requires { typename _Tp::template rebind<_Up>::other; }
+  struct __rebind<_Tp, _Up>
+#else
   struct __rebind<_Tp, _Up,
  __void_t::other>>
+#endif
   {
using type = typename _Tp::template rebind<_Up>::other;
 
@@ -89,6 +103,135 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   using __pocs = typename _Tp::propagate_on_container_swap;
 template
   using __equal = __type_identity;
+
+// __has_allocate_hint is true if a.allocate(n, hint) is well-formed.
+#if __cpp_concepts
+template
+  static constexpr bool __has_allocate_hint
+ 

[gcc r15-3133] libstdc++: Optimize __try_use_facet for const types

2024-08-23 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:952e67c0d131300f263d729a0fe07bc3655dad27

commit r15-3133-g952e67c0d131300f263d729a0fe07bc3655dad27
Author: Jonathan Wakely 
Date:   Wed May 22 16:49:31 2024 +0100

libstdc++: Optimize __try_use_facet for const types

LWG 436 confirmed that const-qualified types are valid arguments for
Facet template parameters (but volatile-qualified types are not). Use the
fast path in std::use_facet and std::has_facet for const T as well as T.

libstdc++-v3/ChangeLog:

* include/bits/locale_classes.tcc (__try_use_facet): Also avoid
dynamic_cast for const-qualified facet types.

Diff:
---
 libstdc++-v3/include/bits/locale_classes.tcc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/bits/locale_classes.tcc 
b/libstdc++-v3/include/bits/locale_classes.tcc
index c79574e58de8..d5ef1911057b 100644
--- a/libstdc++-v3/include/bits/locale_classes.tcc
+++ b/libstdc++-v3/include/bits/locale_classes.tcc
@@ -110,7 +110,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // We know these standard facets are always installed in every locale
   // so dynamic_cast always succeeds, just use static_cast instead.
 #define _GLIBCXX_STD_FACET(...) \
-  if _GLIBCXX_CONSTEXPR (__is_same(_Facet, __VA_ARGS__)) \
+  if _GLIBCXX_CONSTEXPR (__is_same(const _Facet, const __VA_ARGS__)) \
return static_cast(__facets[__i])
 
   _GLIBCXX_STD_FACET(ctype);


[gcc r15-3124] libstdc++: Make std::vector::reference constructor private [PR115098]

2024-08-23 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:b25b101bc380004b82e25d2b1ef306856c75d864

commit r15-3124-gb25b101bc380004b82e25d2b1ef306856c75d864
Author: Jonathan Wakely 
Date:   Wed Aug 21 21:19:46 2024 +0100

libstdc++: Make std::vector::reference constructor private [PR115098]

The standard says this constructor should be private.  LWG 4141 proposes
to remove it entirely. We still need it, but it doesn't need to be
public.

For std::bitset the default constructor is already private (and never
even defined) but there's a non-standard constructor that's public, but
doesn't need to be.

libstdc++-v3/ChangeLog:

PR libstdc++/115098
* include/bits/stl_bvector.h (_Bit_reference): Make default
constructor private. Declare vector and bit iterators as
friends.
* include/std/bitset (bitset::reference): Make constructor and
data members private.
* testsuite/20_util/bitset/115098.cc: New test.
* testsuite/23_containers/vector/bool/115098.cc: New test.

Diff:
---
 libstdc++-v3/include/bits/stl_bvector.h| 12 +---
 libstdc++-v3/include/std/bitset|  5 +
 libstdc++-v3/testsuite/20_util/bitset/115098.cc| 11 +++
 libstdc++-v3/testsuite/23_containers/vector/bool/115098.cc |  8 
 4 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/libstdc++-v3/include/bits/stl_bvector.h 
b/libstdc++-v3/include/bits/stl_bvector.h
index c45b7ff3320d..42261ac5915f 100644
--- a/libstdc++-v3/include/bits/stl_bvector.h
+++ b/libstdc++-v3/include/bits/stl_bvector.h
@@ -81,6 +81,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 
   struct _Bit_reference
   {
+  private:
+template friend class vector;
+friend struct _Bit_iterator;
+friend struct _Bit_const_iterator;
+
+_GLIBCXX20_CONSTEXPR
+_Bit_reference() _GLIBCXX_NOEXCEPT : _M_p(0), _M_mask(0) { }
+
 _Bit_type * _M_p;
 _Bit_type _M_mask;
 
@@ -88,9 +96,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 _Bit_reference(_Bit_type * __x, _Bit_type __y)
 : _M_p(__x), _M_mask(__y) { }
 
-_GLIBCXX20_CONSTEXPR
-_Bit_reference() _GLIBCXX_NOEXCEPT : _M_p(0), _M_mask(0) { }
-
+  public:
 #if __cplusplus >= 201103L
 _Bit_reference(const _Bit_reference&) = default;
 #endif
diff --git a/libstdc++-v3/include/std/bitset b/libstdc++-v3/include/std/bitset
index e5d677ff059c..2e82a0e289d5 100644
--- a/libstdc++-v3/include/std/bitset
+++ b/libstdc++-v3/include/std/bitset
@@ -870,10 +870,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_WordT* _M_wp;
size_t  _M_bpos;
 
-   // left undefined
-   reference();
-
-  public:
_GLIBCXX23_CONSTEXPR
reference(bitset& __b, size_t __pos) _GLIBCXX_NOEXCEPT
{
@@ -881,6 +877,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
  _M_bpos = _Base::_S_whichbit(__pos);
}
 
+  public:
 #if __cplusplus >= 201103L
reference(const reference&) = default;
 #endif
diff --git a/libstdc++-v3/testsuite/20_util/bitset/115098.cc 
b/libstdc++-v3/testsuite/20_util/bitset/115098.cc
new file mode 100644
index ..52d6a0ec3781
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/bitset/115098.cc
@@ -0,0 +1,11 @@
+// { dg-do compile { target c++11 } }
+
+#include 
+
+using namespace std;
+
+static_assert( ! is_default_constructible::reference>::value,
+"std::bitset::reference is not default constructible");
+
+static_assert( ! is_constructible::reference, bitset<10>&, 
size_t>::value,
+"std::bitset::reference is not default constructible");
diff --git a/libstdc++-v3/testsuite/23_containers/vector/bool/115098.cc 
b/libstdc++-v3/testsuite/23_containers/vector/bool/115098.cc
new file mode 100644
index ..3df8b8017950
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/bool/115098.cc
@@ -0,0 +1,8 @@
+// { dg-do compile { target c++11 } }
+
+#include 
+
+static_assert(
+!std::is_default_constructible::reference>::value,
+"std::vector::reference is not default constructible"
+);


  1   2   3   >