Re: [PATCH] Avoid vector -Wfree-nonheap-object warnings

2024-05-29 Thread Jonathan Wakely
On Tue, 28 May 2024 at 21:55, François Dumont  wrote:
>
> I can indeed restore _M_initialize_dispatch as it was before. It was not
> fixing my initial problem. I simply kept the code simplification.
>
>  libstdc++: Use RAII to replace try/catch blocks
>
>  Move _Guard into std::vector declaration and use it to guard all
> calls to
>  vector _M_allocate.
>
>  Doing so the compiler has more visibility on what is done with the
> pointers
>  and do not raise anymore the -Wfree-nonheap-object warning.
>
>  libstdc++-v3/ChangeLog:
>
>  * include/bits/vector.tcc (_Guard): Move all the nested
> duplicated class...
>  * include/bits/stl_vector.h (_Guard_alloc): ...here and rename.
>  (_M_allocate_and_copy): Use latter.
>  (_M_initialize_dispatch): Small code simplification.
>  (_M_range_initialize): Likewise and set _M_finish first
> from the result
>  of __uninitialize_fill_n_a that can throw.
>
> Tested under Linux x86_64.
>
> Ok to commit ?

OK, thanks


>
> François
>
> On 28/05/2024 12:30, Jonathan Wakely wrote:
> > On Mon, 27 May 2024 at 05:37, François Dumont  wrote:
> >> Here is a new version working also in C++98.
> > Can we use a different solution that doesn't involve an explicit
> > template argument list for that __uninitialized_fill_n_a call?
> >
> > -+this->_M_impl._M_finish = std::__uninitialized_fill_n_a
> > ++this->_M_impl._M_finish =
> > ++  std::__uninitialized_fill_n_a
> > +  (__start, __n, __value, _M_get_Tp_allocator());
> >
> > Using _M_fill_initialize solves the problem :-)
> >
> >
> >
> >> Note that I have this failure:
> >>
> >> FAIL: 23_containers/vector/types/1.cc  -std=gnu++98 (test for excess 
> >> errors)
> >>
> >> but it's already failing on master, my patch do not change anything.
> > Yes, that's been failing for ages.
> >
> >> Tested under Linux x64,
> >>
> >> still ok to commit ?
> >>
> >> François
> >>
> >> On 24/05/2024 16:17, Jonathan Wakely wrote:
> >>> On Thu, 23 May 2024 at 18:38, François Dumont  
> >>> wrote:
> >>>> On 23/05/2024 15:31, Jonathan Wakely wrote:
> >>>>> On 23/05/24 06:55 +0200, François Dumont wrote:
> >>>>>> As explained in this email:
> >>>>>>
> >>>>>> https://gcc.gnu.org/pipermail/libstdc++/2024-April/058552.html
> >>>>>>
> >>>>>> I experimented -Wfree-nonheap-object because of my enhancements on
> >>>>>> algos.
> >>>>>>
> >>>>>> So here is a patch to extend the usage of the _Guard type to other
> >>>>>> parts of vector.
> >>>>> Nice, that fixes the warning you were seeing?
> >>>> Yes ! I indeed forgot to say so :-)
> >>>>
> >>>>
> >>>>> We recently got a bug report about -Wfree-nonheap-object in
> >>>>> std::vector, but that is coming from _M_realloc_append which already
> >>>>> uses the RAII guard :-(
> >>>>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115016
> >>>> Note that I also had to move call to __uninitialized_copy_a before
> >>>> assigning this->_M_impl._M_start so get rid of the -Wfree-nonheap-object
> >>>> warn. But _M_realloc_append is already doing potentially throwing
> >>>> operations before assigning this->_M_impl so it must be something else.
> >>>>
> >>>> Though it made me notice another occurence of _Guard in this method. Now
> >>>> replaced too in this new patch.
> >>>>
> >>>>libstdc++: Use RAII to replace try/catch blocks
> >>>>
> >>>>Move _Guard into std::vector declaration and use it to guard all
> >>>> calls to
> >>>>vector _M_allocate.
> >>>>
> >>>>Doing so the compiler has more visibility on what is done with the
> >>>> pointers
> >>>>and do not raise anymore the -Wfree-nonheap-object warning.
> >>>>
> >>>>libstdc++-v3/ChangeLog:
> >>>>
> >>>>* include/bits/vector.tcc (_Guard): Move all the nested
> >>>> duplicated class...
> >>>>* include/bits/stl_vector.h (_Guard_alloc): ...here.
> &

Re: libstdc++ and missing RUNPATH

2024-05-29 Thread Jonathan Wakely via Gcc
On Wed, 29 May 2024 at 09:15, Sad Clouds via Gcc  wrote:
>
> On Wed, 29 May 2024 09:05:50 +0200
> Richard Biener  wrote:
>
> > If you build an executable to pick up libstdc++ via a RUNPATH that apps 
> > RUNPATH
> > should apply to libgcc as well.  If you use LD_LIBRARY_PATH the story
> > is the same.
> >
> > So what's your actual failure mode?
>
> Hello, the concern I have is that GCC binaries themselves
> under /opt/gcc-14.1.0 may depend on symbols in libstdc++ and I would
> like to have GCC compilers to be self-contained and without any
> LD_LIBRARY_PATH hacks. So given:
>
> $ ldd /opt/gcc-14.1.0/lib/libstdc++.so.6
> /opt/gcc-14.1.0/lib/libstdc++.so.6:
> libm.so.5 => /lib/libm.so.5 (0x5486f1dc8000)
> libc.so.7 => /lib/libc.so.7 (0x5486f07e5000)
> libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x5486f1ff)
>
> So two issues I can think of:
>
> 1. Some GCC binaries hardcode RUNPATH and use

Binaries, or just libraries?

> /opt/gcc-14.1.0/lib/libgcc_s.so.1 while other GCC binaries pick up
> /lib/libgcc_s.so.1 instead. Seems somewhat inconsistent and may result
> in weird behaviour if there are ABI changes, etc.

Have you observed an actual failure?

> 2. FreeBSD uses LLVM, but maybe some low-level linker stuff
> currently depends on /lib/libgcc_s.so.1? This may change in the future
> if LLVM decide to implement their own low-level functions and remove
> this dependency completely.
>
> The RUNPATH is already hard coded for other GCC libraries, so I'm not
> sure why this is not done for libstdc++ also.

The sanitizer libraries use a RUNPATH, I don't know why. That doesn't
imply that libstdc++ should do so too.

GCC documents that it doesn't use RPATH/RUNPATH:
https://gcc.gnu.org/faq.html#rpath
https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dynamic_or_shared.html#manual.intro.using.linkage.dynamic



>
> Thanks.


Re: [PATCH] libstdc++: Build libbacktrace and 19_diagnostics/stacktrace with -funwind-tables [PR111641]

2024-05-28 Thread Jonathan Wakely
On Tue, 28 May 2024 at 15:25, Rainer Orth  wrote:
>
> Several of the 19_diagnostics/stacktrace tests FAIL on Solaris/SPARC (32
> and 64-bit), Solaris/x86 (32-bit only), and several other targets:
>
> FAIL: 19_diagnostics/stacktrace/current.cc  -std=gnu++23 execution test
> FAIL: 19_diagnostics/stacktrace/current.cc  -std=gnu++26 execution test
> FAIL: 19_diagnostics/stacktrace/entry.cc  -std=gnu++23 execution test
> FAIL: 19_diagnostics/stacktrace/entry.cc  -std=gnu++26 execution test
> FAIL: 19_diagnostics/stacktrace/output.cc  -std=gnu++23 execution test
> FAIL: 19_diagnostics/stacktrace/output.cc  -std=gnu++26 execution test
> FAIL: 19_diagnostics/stacktrace/stacktrace.cc  -std=gnu++23 execution test
> FAIL: 19_diagnostics/stacktrace/stacktrace.cc  -std=gnu++26 execution test
>
> As it turns out, both the copy of libbacktrace in libstdc++ and the
> testcases proper need to compiled with -funwind-tables, as is done for
> libbacktrace itself.
>
> This isn't an issue on Linux/x86_64 and Solaris/amd64 since 64-bit x86
> always defaults to -funwind-tables.  32-bit x86 does, too, when
> -fomit-frame-pointer is enabled as on Linux/i686, but unlike
> Solaris/i386.
>
> So this patch always enables the option both for the libbacktrace copy
> and the testcases.
>
> Tested on i386-pc-solaris2.11, sparc-sun-solaris2.11, and
> x86_64-pc-linux-gnu.
>
> Ok for trunk?

OK for trunk and gcc-14. Thanks for figuring out the problem here!


>
> Rainer
>
> --
> -
> Rainer Orth, Center for Biotechnology, Bielefeld University
>
>
> 2024-05-23  Rainer Orth  
>
> libstdc++-v3:
> PR libstdc++/111641
> * src/libbacktrace/Makefile.am (AM_CFLAGS): Add -funwind-tables.
> * src/libbacktrace/Makefile.in: Regenerate.
>
> * testsuite/19_diagnostics/stacktrace/current.cc (dg-options): Add
> -funwind-tables.
> * testsuite/19_diagnostics/stacktrace/entry.cc: Likewise.
> * testsuite/19_diagnostics/stacktrace/hash.cc: Likewise.
> * testsuite/19_diagnostics/stacktrace/output.cc: Likewise.
> * testsuite/19_diagnostics/stacktrace/stacktrace.cc: Likewise.
>



Re: [PATCH] libstdc++: Avoid MMX return types from __builtin_shufflevector

2024-05-28 Thread Jonathan Wakely
On Wed, 15 May 2024 at 20:50, Matthias Kretz  wrote:
>
> Tested on aarch64-linux-gnu, arm-linux-gnueabihf, powerpc64le-linux-gnu,
> x86_64-linux-gnu (-m64, -m32, -mx32), and arm-linux-gnueabi
>
> OK for trunk?

OK

> And when backporting, should I squash it with the commit that
> introduced the regression?

I don't mind about that. If you cherry-pick them next to each other
and push them at the same time, nobody's going to end up using the
broken commit before the fix. It's fine to squash it if you prefer to
though.

OK for backports either way.

>
>  8< ---
>
> This resolves a regression on i686 that was introduced with
> r15-429-gfb1649f8b4ad50.
>
> Signed-off-by: Matthias Kretz 
>
> libstdc++-v3/ChangeLog:
>
> PR libstdc++/114958
> * include/experimental/bits/simd.h (__as_vector): Don't use
> vector_size(8) on __i386__.
> (__vec_shuffle): Never return MMX vectors, widen to 16 bytes
> instead.
> (concat): Fix padding calculation to pick up widening logic from
> __as_vector.
> ---
>  libstdc++-v3/include/experimental/bits/simd.h | 39 +--
>  1 file changed, 28 insertions(+), 11 deletions(-)
>
>
> --
> ──
>  Dr. Matthias Kretz   https://mattkretz.github.io
>  GSI Helmholtz Centre for Heavy Ion Research   https://gsi.de
>  stdₓ::simd
> ──


[gcc r13-8804] libstdc++: Guard use of sized deallocation [PR114940]

2024-05-28 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:67434fec24bef0faeec0eb402f82ca7e43a4a112

commit r13-8804-g67434fec24bef0faeec0eb402f82ca7e43a4a112
Author: Jonathan Wakely 
Date:   Wed May 22 10:32:43 2024 +0100

libstdc++: Guard use of sized deallocation [PR114940]

Clang does not enable -fsized-deallocation by default, which means it
can't compile our  header.

Make the __cpp_lib_generator macro depend on the compiler-defined
__cpp_sized_deallocation macro, and change  to use unsized
deallocation when __cpp_sized_deallocation isn't defined.

libstdc++-v3/ChangeLog:

PR libstdc++/114940
* include/std/stacktrace (_GLIBCXX_SIZED_DELETE): New macro.
(basic_stacktrace::_Impl::_M_deallocate): Use it.

(cherry picked from commit b2fdd508d7e63158e9d2a6dd04f901d02900def3)

Diff:
---
 libstdc++-v3/include/std/stacktrace | 13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/std/stacktrace 
b/libstdc++-v3/include/std/stacktrace
index 8f09467d751..3d8a085a6a9 100644
--- a/libstdc++-v3/include/std/stacktrace
+++ b/libstdc++-v3/include/std/stacktrace
@@ -600,6 +600,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #else
 # define _GLIBCXX_OPERATOR_NEW ::operator new
 # define _GLIBCXX_OPERATOR_DELETE ::operator delete
+#endif
+
+#if __cpp_sized_deallocation
+# define _GLIBCXX_SIZED_DELETE(T, p, n) \
+  _GLIBCXX_OPERATOR_DELETE((p), (n) * sizeof(T))
+#else
+# define _GLIBCXX_SIZED_DELETE(T, p, n) _GLIBCXX_OPERATOR_DELETE(p)
 #endif
 
// Precondition: _M_frames == nullptr && __n != 0
@@ -641,8 +648,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  if (_M_capacity)
{
  if constexpr (is_same_v>)
-   _GLIBCXX_OPERATOR_DELETE (static_cast(_M_frames),
- _M_capacity * sizeof(value_type));
+   _GLIBCXX_SIZED_DELETE(value_type,
+ static_cast(_M_frames),
+ _M_capacity);
  else
__alloc.deallocate(_M_frames, _M_capacity);
  _M_frames = nullptr;
@@ -650,6 +658,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
}
 
+#undef _GLIBCXX_SIZED_DELETE
 #undef _GLIBCXX_OPERATOR_DELETE
 #undef _GLIBCXX_OPERATOR_NEW


Re: [PATCH] Avoid vector -Wfree-nonheap-object warnings

2024-05-28 Thread Jonathan Wakely
On Mon, 27 May 2024 at 05:37, François Dumont  wrote:
>
> Here is a new version working also in C++98.

Can we use a different solution that doesn't involve an explicit
template argument list for that __uninitialized_fill_n_a call?

-+this->_M_impl._M_finish = std::__uninitialized_fill_n_a
++this->_M_impl._M_finish =
++  std::__uninitialized_fill_n_a
+  (__start, __n, __value, _M_get_Tp_allocator());

Using _M_fill_initialize solves the problem :-)



>
> Note that I have this failure:
>
> FAIL: 23_containers/vector/types/1.cc  -std=gnu++98 (test for excess errors)
>
> but it's already failing on master, my patch do not change anything.

Yes, that's been failing for ages.

>
> Tested under Linux x64,
>
> still ok to commit ?
>
> François
>
> On 24/05/2024 16:17, Jonathan Wakely wrote:
> > On Thu, 23 May 2024 at 18:38, François Dumont  wrote:
> >>
> >> On 23/05/2024 15:31, Jonathan Wakely wrote:
> >>> On 23/05/24 06:55 +0200, François Dumont wrote:
> >>>> As explained in this email:
> >>>>
> >>>> https://gcc.gnu.org/pipermail/libstdc++/2024-April/058552.html
> >>>>
> >>>> I experimented -Wfree-nonheap-object because of my enhancements on
> >>>> algos.
> >>>>
> >>>> So here is a patch to extend the usage of the _Guard type to other
> >>>> parts of vector.
> >>> Nice, that fixes the warning you were seeing?
> >> Yes ! I indeed forgot to say so :-)
> >>
> >>
> >>> We recently got a bug report about -Wfree-nonheap-object in
> >>> std::vector, but that is coming from _M_realloc_append which already
> >>> uses the RAII guard :-(
> >>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115016
> >> Note that I also had to move call to __uninitialized_copy_a before
> >> assigning this->_M_impl._M_start so get rid of the -Wfree-nonheap-object
> >> warn. But _M_realloc_append is already doing potentially throwing
> >> operations before assigning this->_M_impl so it must be something else.
> >>
> >> Though it made me notice another occurence of _Guard in this method. Now
> >> replaced too in this new patch.
> >>
> >>   libstdc++: Use RAII to replace try/catch blocks
> >>
> >>   Move _Guard into std::vector declaration and use it to guard all
> >> calls to
> >>   vector _M_allocate.
> >>
> >>   Doing so the compiler has more visibility on what is done with the
> >> pointers
> >>   and do not raise anymore the -Wfree-nonheap-object warning.
> >>
> >>   libstdc++-v3/ChangeLog:
> >>
> >>   * include/bits/vector.tcc (_Guard): Move all the nested
> >> duplicated class...
> >>   * include/bits/stl_vector.h (_Guard_alloc): ...here.
> >>   (_M_allocate_and_copy): Use latter.
> >>   (_M_initialize_dispatch): Likewise and set _M_finish first
> >> from the result
> >>   of __uninitialize_fill_n_a that can throw.
> >>   (_M_range_initialize): Likewise.
> >>
> >>>> diff --git a/libstdc++-v3/include/bits/stl_vector.h
> >>>> b/libstdc++-v3/include/bits/stl_vector.h
> >>>> index 31169711a48..4ea74e3339a 100644
> >>>> --- a/libstdc++-v3/include/bits/stl_vector.h
> >>>> +++ b/libstdc++-v3/include/bits/stl_vector.h
> >>>> @@ -1607,6 +1607,39 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
> >>>>clear() _GLIBCXX_NOEXCEPT
> >>>>{ _M_erase_at_end(this->_M_impl._M_start); }
> >>>>
> >>>> +private:
> >>>> +  // RAII guard for allocated storage.
> >>>> +  struct _Guard
> >>> If it's being defined at class scope instead of locally in a member
> >>> function, I think a better name would be good. Maybe _Ptr_guard or
> >>> _Dealloc_guard or something.
> >> _Guard_alloc chosen.
> >>>> +  {
> >>>> +pointer _M_storage;// Storage to deallocate
> >>>> +size_type _M_len;
> >>>> +_Base& _M_vect;
> >>>> +
> >>>> +_GLIBCXX20_CONSTEXPR
> >>>> +_Guard(pointer __s, size_type __l, _Base& __vect)
> >>>> +: _M_storage(__s), _M_len(__l), _M_vect(__vect)
> >>>> +{ }
> >>>> +
> >>>> +_GLIBCXX20_CONSTEXPR
> >>>&

Re: [PATCH] Fix -Wstringop-overflow warning in 23_containers/vector/types/1.cc

2024-05-28 Thread Jonathan Wakely

On 27/05/24 22:07 +0200, François Dumont wrote:

In C++98 this test fails with:

Excess errors:
/home/fdumont/dev/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/bits/stl_algobase.h:452: 
warning: 'void* __builtin_memcpy(void*, const void*, long unsigned 
int)' writing between 2 and 9223372036854775806 bytes into a region of 
size 0 overflows the destination [-Wstringop-overflow=]


The attached patch avoids this warning.

    libstdc++: Fix -Wstringop-overflow warning coming from std::vector

    Make vector<>::_M_range_insert implementation more transparent to 
the compiler checks.


    Extend local copies of members to the whole method scope so that 
all branches benefit

    from those.

    libstdc++-v3/ChangeLog:

    * include/bits/vector.tcc
    (std::vector<>::_M_range_insert(iterator, _FwdIt, _FwdIt, 
forward_iterator_tag)):

    Use local copies of members to call the different algorithms.

Ok to commit if all tests passes ?

François



diff --git a/libstdc++-v3/include/bits/vector.tcc 
b/libstdc++-v3/include/bits/vector.tcc
index 36b27dce7b9..671929dee55 100644
--- a/libstdc++-v3/include/bits/vector.tcc
+++ b/libstdc++-v3/include/bits/vector.tcc
@@ -885,83 +885,80 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
  {
if (__first != __last)
  {
+   // Make local copies of these members because the compiler
+   // thinks the allocator can alter them if 'this' is globally
+   // reachable.
+   pointer __start = this->_M_impl._M_start;
+   pointer __end = this->_M_impl._M_end_of_storage;
+   pointer __finish = this->_M_impl._M_finish;
+   pointer __pos = __position.base();
+   _Tp_alloc_type& __allocator = _M_get_Tp_allocator();
+
+   if (__pos < __start || __finish < __pos)
+ __builtin_unreachable();


I don't think we should use __builtin_unreachable for something which
is not an invariant of the class. The __position argument is supplied
by the user, so we should not make promises about it being valid,
because we can't know that.

We can promise that __start <= __finish, and that __finish <= end,
because we control those. We can't promise the user won't pass in a
bad __position. Although it's undefined for the user to do that, using
__builtin_unreachable() here makes the effects worse, and makes it
harder to debug.

Also, (__pos < __start) might already trigger undefined behaviour for
fancy pointers, if they don't point to the same memory region.

So this change is not OK.



+
const size_type __n = std::distance(__first, __last);
-   if (size_type(this->_M_impl._M_end_of_storage
- - this->_M_impl._M_finish) >= __n)
+   if (size_type(__end - __finish) >= __n)
  {
-   const size_type __elems_after = end() - __position;
-   pointer __old_finish(this->_M_impl._M_finish);
+   const size_type __elems_after = __end - __pos;
+   pointer __old_finish(__finish);
if (__elems_after > __n)
  {
_GLIBCXX_ASAN_ANNOTATE_GROW(__n);
-   std::__uninitialized_move_a(this->_M_impl._M_finish - __n,
-   this->_M_impl._M_finish,
-   this->_M_impl._M_finish,
-   _M_get_Tp_allocator());
-   this->_M_impl._M_finish += __n;
+   __finish = std::__uninitialized_move_a
+ (__finish - __n, __finish, __finish, __allocator);
_GLIBCXX_ASAN_ANNOTATE_GREW(__n);
-   _GLIBCXX_MOVE_BACKWARD3(__position.base(),
-   __old_finish - __n, __old_finish);
-   std::copy(__first, __last, __position);
+   _GLIBCXX_MOVE_BACKWARD3
+ (__pos, __old_finish - __n, __old_finish);
+   std::copy(__first, __last, __pos);
  }
else
  {
_ForwardIterator __mid = __first;
std::advance(__mid, __elems_after);
_GLIBCXX_ASAN_ANNOTATE_GROW(__n);
-   std::__uninitialized_copy_a(__mid, __last,
-   this->_M_impl._M_finish,
-   _M_get_Tp_allocator());
-   this->_M_impl._M_finish += __n - __elems_after;
+   __finish = std::__uninitialized_copy_a
+ (__mid, __last, __finish, __allocator);
_GLIBCXX_ASAN_ANNOTATE_GREW(__n - __elems_after);
-   std::__uninitialized_move_a(__position.base(),
-   __old_finish,
-   this->_M_impl._M_finish,
-   

[gcc r14-10250] libstdc++: Guard use of sized deallocation [PR114940]

2024-05-28 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:89dff1488ef3fde11f6451e5f9817e14bcd6a873

commit r14-10250-g89dff1488ef3fde11f6451e5f9817e14bcd6a873
Author: Jonathan Wakely 
Date:   Wed May 22 10:32:43 2024 +0100

libstdc++: Guard use of sized deallocation [PR114940]

Clang does not enable -fsized-deallocation by default, which means it
can't compile our  and  headers.

Make the __cpp_lib_generator macro depend on the compiler-defined
__cpp_sized_deallocation macro, and change  to use unsized
deallocation when __cpp_sized_deallocation isn't defined.

libstdc++-v3/ChangeLog:

PR libstdc++/114940
* include/bits/version.def (generator): Depend on
__cpp_sized_deallocation.
* include/bits/version.h: Regenerate.
* include/std/stacktrace (_GLIBCXX_SIZED_DELETE): New macro.
(basic_stacktrace::_Impl::_M_deallocate): Use it.

(cherry picked from commit b2fdd508d7e63158e9d2a6dd04f901d02900def3)

Diff:
---
 libstdc++-v3/include/bits/version.def |  2 +-
 libstdc++-v3/include/bits/version.h   |  2 +-
 libstdc++-v3/include/std/stacktrace   | 13 +++--
 3 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/libstdc++-v3/include/bits/version.def 
b/libstdc++-v3/include/bits/version.def
index 5c0477fb61e..e5f4c4c13c0 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -1642,7 +1642,7 @@ ftms = {
   values = {
 v = 202207;
 cxxmin = 23;
-extra_cond = "__glibcxx_coroutine";
+extra_cond = "__glibcxx_coroutine && __cpp_sized_deallocation";
   };
 };
 
diff --git a/libstdc++-v3/include/bits/version.h 
b/libstdc++-v3/include/bits/version.h
index 65e708c73fb..ad418d46664 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -1824,7 +1824,7 @@
 #undef __glibcxx_want_forward_like
 
 #if !defined(__cpp_lib_generator)
-# if (__cplusplus >= 202100L) && (__glibcxx_coroutine)
+# if (__cplusplus >= 202100L) && (__glibcxx_coroutine && 
__cpp_sized_deallocation)
 #  define __glibcxx_generator 202207L
 #  if defined(__glibcxx_want_all) || defined(__glibcxx_want_generator)
 #   define __cpp_lib_generator 202207L
diff --git a/libstdc++-v3/include/std/stacktrace 
b/libstdc++-v3/include/std/stacktrace
index d217d63af3b..962dbed7a41 100644
--- a/libstdc++-v3/include/std/stacktrace
+++ b/libstdc++-v3/include/std/stacktrace
@@ -551,6 +551,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #else
 # define _GLIBCXX_OPERATOR_NEW ::operator new
 # define _GLIBCXX_OPERATOR_DELETE ::operator delete
+#endif
+
+#if __cpp_sized_deallocation
+# define _GLIBCXX_SIZED_DELETE(T, p, n) \
+  _GLIBCXX_OPERATOR_DELETE((p), (n) * sizeof(T))
+#else
+# define _GLIBCXX_SIZED_DELETE(T, p, n) _GLIBCXX_OPERATOR_DELETE(p)
 #endif
 
// Precondition: _M_frames == nullptr && __n != 0
@@ -592,8 +599,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  if (_M_capacity)
{
  if constexpr (is_same_v>)
-   _GLIBCXX_OPERATOR_DELETE (static_cast(_M_frames),
- _M_capacity * sizeof(value_type));
+   _GLIBCXX_SIZED_DELETE(value_type,
+ static_cast(_M_frames),
+ _M_capacity);
  else
__alloc.deallocate(_M_frames, _M_capacity);
  _M_frames = nullptr;
@@ -601,6 +609,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
}
 
+#undef _GLIBCXX_SIZED_DELETE
 #undef _GLIBCXX_OPERATOR_DELETE
 #undef _GLIBCXX_OPERATOR_NEW


Re: [PATCH] libstdc++: Fix up 19_diagnostics/stacktrace/hash.cc on 13 branch

2024-05-28 Thread Jonathan Wakely
On Mon, 27 May 2024 at 09:26, Jakub Jelinek  wrote:
>
> Hi!
>
> The r13-8207-g17acf9fbeb10d7adad commit changed some tests to use
> -lstdc++exp instead of -lstdc++_libbacktrace, but it didn't change
> the 19_diagnostics/stacktrace/hash.cc test, presumably because
> when it was added on the trunk, it already had -lstdc++exp and
> it was changed to -lstdc++_libbacktrace only in the
> r13-8067-g16635b89f36c07b9e0 cherry-pick.
>
> The test fails with
> /usr/bin/ld: cannot find -lstdc++_libbacktrace
> collect2: error: ld returned 1 exit status
> compiler exited with status 1
> FAIL: 19_diagnostics/stacktrace/hash.cc (test for excess errors)
> without this (while the library is still built, it isn't added in
> -L options).

Ah yes, because r13-8207-g17acf9fbeb10d7 changed the -L flags used for testing.

I wonder why I didn't see this failure though. It must have found the
lib in an already-installed path.

> Ok for 13 branch?

OK, thanks.


>
> I think the r13-8067 cherry-pick hasn't been applied to 12 branch,
> so we don't need it there.
>
> 2024-05-27  Jakub Jelinek  
>
> * testsuite/19_diagnostics/stacktrace/hash.cc: Adjust
> dg-options to use -lstdc++exp.
>
> --- libstdc++-v3/testsuite/19_diagnostics/stacktrace/hash.cc.jj 2023-11-22 
> 11:03:28.812657550 +0100
> +++ libstdc++-v3/testsuite/19_diagnostics/stacktrace/hash.cc2024-05-27 
> 10:18:44.900058884 +0200
> @@ -1,4 +1,4 @@
> -// { dg-options "-std=gnu++23 -lstdc++_libbacktrace" }
> +// { dg-options "-std=gnu++23 -lstdc++exp" }
>  // { dg-do run { target c++23 } }
>  // { dg-require-effective-target stacktrace }
>
>
>
> Jakub
>



Re: configure adds -std=gnu++11 to CXX variable

2024-05-28 Thread Jonathan Wakely via Gcc
On Tue, 28 May 2024, 02:51 Paul Eggert,  wrote:

> On 2024-05-27 12:18, Jakub Jelinek wrote:
> > Maybe respect the carefully chosen compiler default (unless explicitly
> > overridden in configure.ac)?
>
> Autoconf gave up on that idea long ago, as we had bad experiences with
> compiler defaults being chosen for the convenience of distro maintainers
> rather than for application developers and builders. Compilers were
> still defaulting to K long after that made little sense.



What has that got to do with C++ dialects?

GCC defaults to C++17 in versions that have good, stable C++17 support. So
does Clang these days. So what problem are you trying to solve for C++ here?


It was a bit
> like what we're still experiencing with _FILE_OFFSET_BITS defaulting to
> 32 on x86 GNU/Linux.
>
> Using the compiler default puts you at the mercy of the distro. It's not
> always wrong to do that - which is why developers and builders should
> have an option - but it's not always right either.
>

I am not aware of any distro ever changing the default -std setting for g++
or clang++. Are you attempting to solve a non-problem, but introducing new
ones?


Re: configure adds -std=gnu++11 to CXX variable

2024-05-28 Thread Jonathan Wakely via Gcc
On Tue, 28 May 2024, 07:24 Florian Weimer via Gcc,  wrote:

> * Paul Eggert:
>
> > On 2024-05-27 03:35, Florian Weimer wrote:
> >> Does this turn on experimental language modes by default?  That's
> >> probably not what we want.
> >
> > What do C++ developers want these days? Autoconf should have a
> > reasonable default, and C++11 is surely not a good default anymore.
>
> It's still a good default for GCC 5.
>
> GCC developers will correct me, but I think the default C++ dialect is
> updated to a newer version once the implementation is reasonably
> complete and bugs have been ironed out.
>

Correct.

Please DO NOT default to C++20 for any current version of GCC, that's an
ABI disaster waiting to happen. There is no version of GCC with stable
C++20 support.



> This is different from the C front end, where it took close to 40 years
> (from the introduction of void * into C) to activate type checking for
> pointer types by default.
>
> >> It would be better to have an option to raise the C++ mode to at least a
> >> certain revision, and otherwise use the default.
> >
> > That option is already available. For example, a builder who doesn't
> > want C++23 can use './configure ac_cv_prog_cxx_cxx23=no', and a
> > developer can discourage C++23 by putting ':
> > ${ac_cv_prog_cxx_cxx23=no}' early in configure.ac.
>

It should not be opt out.

But if you make this change I'll very loudly suggest that everybody use
that in every autoconf-based C++ program. Then you'll probably need some
other solution in 5 years to workaround the fact that that option is
ubiquitous and needs to be ignored or overridden because people want C++20
to be used




> But that is not the same thing.  If a project uses C++14 constructs,
> wouldn't it make sense to tell configure to try to get (likely
> experimental) support for it if the compiler does not enable C++14 by
> default?  And if the system is already at C++17, leave it at that?
>
> Setting C++14 unconditionally could be incompatible with used system
> libraries, which assume C++17 support because the distribution is aware
> that the system compiler supports C++17.
>
> Thanks,
> Florian
>
>


Re: [PATCH] Avoid vector -Wfree-nonheap-object warnings

2024-05-24 Thread Jonathan Wakely
On Thu, 23 May 2024 at 18:38, François Dumont  wrote:
>
>
> On 23/05/2024 15:31, Jonathan Wakely wrote:
> > On 23/05/24 06:55 +0200, François Dumont wrote:
> >> As explained in this email:
> >>
> >> https://gcc.gnu.org/pipermail/libstdc++/2024-April/058552.html
> >>
> >> I experimented -Wfree-nonheap-object because of my enhancements on
> >> algos.
> >>
> >> So here is a patch to extend the usage of the _Guard type to other
> >> parts of vector.
> >
> > Nice, that fixes the warning you were seeing?
>
> Yes ! I indeed forgot to say so :-)
>
>
> >
> > We recently got a bug report about -Wfree-nonheap-object in
> > std::vector, but that is coming from _M_realloc_append which already
> > uses the RAII guard :-(
> > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115016
>
> Note that I also had to move call to __uninitialized_copy_a before
> assigning this->_M_impl._M_start so get rid of the -Wfree-nonheap-object
> warn. But _M_realloc_append is already doing potentially throwing
> operations before assigning this->_M_impl so it must be something else.
>
> Though it made me notice another occurence of _Guard in this method. Now
> replaced too in this new patch.
>
>  libstdc++: Use RAII to replace try/catch blocks
>
>  Move _Guard into std::vector declaration and use it to guard all
> calls to
>  vector _M_allocate.
>
>  Doing so the compiler has more visibility on what is done with the
> pointers
>  and do not raise anymore the -Wfree-nonheap-object warning.
>
>  libstdc++-v3/ChangeLog:
>
>  * include/bits/vector.tcc (_Guard): Move all the nested
> duplicated class...
>  * include/bits/stl_vector.h (_Guard_alloc): ...here.
>  (_M_allocate_and_copy): Use latter.
>  (_M_initialize_dispatch): Likewise and set _M_finish first
> from the result
>  of __uninitialize_fill_n_a that can throw.
>  (_M_range_initialize): Likewise.
>
> >> diff --git a/libstdc++-v3/include/bits/stl_vector.h
> >> b/libstdc++-v3/include/bits/stl_vector.h
> >> index 31169711a48..4ea74e3339a 100644
> >> --- a/libstdc++-v3/include/bits/stl_vector.h
> >> +++ b/libstdc++-v3/include/bits/stl_vector.h
> >> @@ -1607,6 +1607,39 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
> >>   clear() _GLIBCXX_NOEXCEPT
> >>   { _M_erase_at_end(this->_M_impl._M_start); }
> >>
> >> +private:
> >> +  // RAII guard for allocated storage.
> >> +  struct _Guard
> >
> > If it's being defined at class scope instead of locally in a member
> > function, I think a better name would be good. Maybe _Ptr_guard or
> > _Dealloc_guard or something.
> _Guard_alloc chosen.
> >
> >> +  {
> >> +pointer _M_storage;// Storage to deallocate
> >> +size_type _M_len;
> >> +_Base& _M_vect;
> >> +
> >> +_GLIBCXX20_CONSTEXPR
> >> +_Guard(pointer __s, size_type __l, _Base& __vect)
> >> +: _M_storage(__s), _M_len(__l), _M_vect(__vect)
> >> +{ }
> >> +
> >> +_GLIBCXX20_CONSTEXPR
> >> +~_Guard()
> >> +{
> >> +  if (_M_storage)
> >> +_M_vect._M_deallocate(_M_storage, _M_len);
> >> +}
> >> +
> >> +_GLIBCXX20_CONSTEXPR
> >> +pointer
> >> +_M_release()
> >> +{
> >> +  pointer __res = _M_storage;
> >> +  _M_storage = 0;
> >
> > I don't think the NullablePointer requirements include assigning 0,
> > only from nullptr, which isn't valid in C++98.
> >
> > https://en.cppreference.com/w/cpp/named_req/NullablePointer
> >
> > Please use _M_storage = pointer() instead.
>
> I forgot about user fancy pointer, fixed.
>
>
> >
> >> +  return __res;
> >> +}
> >> +
> >> +  private:
> >> +_Guard(const _Guard&);
> >> +  };
> >> +
> >> protected:
> >>   /**
> >>*  Memory expansion handler.  Uses the member allocation
> >> function to
> >> @@ -1618,18 +1651,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
> >> _M_allocate_and_copy(size_type __n,
> >>  _ForwardIterator __first, _ForwardIterator __last)
> >> {
> >> -  pointer __result = this->_M_allocate(__n);
> >> -  __try
> >> -{
> >> -  std::__uninitialized_cop

Re: [PATCH v3] libstdc++: Fix std::ranges::iota not in numeric [PR108760]

2024-05-24 Thread Jonathan Wakely

On 24/05/24 13:56 -, Michael Levine (BLOOMBERG/ 731 LEX) wrote:

I've attached the v3 version of the patch as a single, squashed patch 
containing all of the changes.  I manually prepended my sign off to the patch.




Signed-off-by: Michael Levine 
---
diff --git a/libstdc++-v3/include/bits/ranges_algo.h 
b/libstdc++-v3/include/bits/ranges_algo.h
index 62faff173bd..d258be0b93f 100644
--- a/libstdc++-v3/include/bits/ranges_algo.h
+++ b/libstdc++-v3/include/bits/ranges_algo.h
@@ -3521,58 +3521,6 @@ namespace ranges

#endif // __glibcxx_ranges_contains

-#if __glibcxx_ranges_iota >= 202202L // C++ >= 23
-
-  template
-struct out_value_result
-{
-  [[no_unique_address]] _Out out;
-  [[no_unique_address]] _Tp value;
-
-  template
-   requires convertible_to
- && convertible_to
-   constexpr
-   operator out_value_result<_Out2, _Tp2>() const &
-   { return {out, value}; }
-
-  template
-   requires convertible_to<_Out, _Out2>
- && convertible_to<_Tp, _Tp2>
-   constexpr
-   operator out_value_result<_Out2, _Tp2>() &&
-   { return {std::move(out), std::move(value)}; }
-};
-
-  template
-using iota_result = out_value_result<_Out, _Tp>;
-
-  struct __iota_fn
-  {
-template _Sent, 
weakly_incrementable _Tp>
-  requires indirectly_writable<_Out, const _Tp&>
-  constexpr iota_result<_Out, _Tp>
-  operator()(_Out __first, _Sent __last, _Tp __value) const
-  {
-   while (__first != __last)
- {
-   *__first = static_cast(__value);
-   ++__first;
-   ++__value;
- }
-   return {std::move(__first), std::move(__value)};
-  }
-
-template _Range>
-  constexpr iota_result, _Tp>
-  operator()(_Range&& __r, _Tp __value) const
-  { return (*this)(ranges::begin(__r), ranges::end(__r), 
std::move(__value)); }
-  };
-
-  inline constexpr __iota_fn iota{};
-
-#endif // __glibcxx_ranges_iota
-
#if __glibcxx_ranges_find_last >= 202207L // C++ >= 23

  struct __find_last_fn
diff --git a/libstdc++-v3/include/bits/ranges_algobase.h 
b/libstdc++-v3/include/bits/ranges_algobase.h
index e26a73a27d6..965b36aed35 100644
--- a/libstdc++-v3/include/bits/ranges_algobase.h
+++ b/libstdc++-v3/include/bits/ranges_algobase.h
@@ -35,6 +35,7 @@
#include 
#include 
#include 
+#include  // __memcpy


Why is this being added here? What is __memcpy?

I don't think out_value_result requires any new headers to be included
here, does it?


#include  // ranges::begin, ranges::range etc.
#include   // __invoke
#include  // __is_byte
@@ -70,6 +71,32 @@ namespace ranges
__is_move_iterator> = true;
  } // namespace __detail

+#if __glibcxx_ranges_iota >= 202202L // C++ >= 23
+
+template
+struct out_value_result
+{
+[[no_unique_address]] _Out out;
+[[no_unique_address]] _Tp value;
+
+template
+   requires convertible_to
+&& convertible_to
+   constexpr
+   operator out_value_result<_Out2, _Tp2>() const &
+   { return {out, value}; }
+
+template
+   requires convertible_to<_Out, _Out2>
+&& convertible_to<_Tp, _Tp2>
+   constexpr
+   operator out_value_result<_Out2, _Tp2>() &&
+   { return {std::move(out), std::move(value)}; }
+};
+
+#endif // __glibcxx_ranges_iota
+
+
  struct __equal_fn
  {
template _Sent1,
diff --git a/libstdc++-v3/include/std/numeric b/libstdc++-v3/include/std/numeric
index c912db4a519..d88f7f02137 100644
--- a/libstdc++-v3/include/std/numeric
+++ b/libstdc++-v3/include/std/numeric
@@ -65,6 +65,10 @@
# include 
#endif

+#if __glibcxx_ranges_iota >= 202202L // C++ >= 23
+#include  // for out_value_result as used by 
std::ranges::iota.  It transitively also brings in , from which 
_Range is used by std::ranges::iota


We generally try to keep lines below 80 columns, or 120 at a push.
This is unnecessarily long, and I don't know what _Range is meant to
be (that's just a template parameter, not something defined in
. Please just use:

#include  // for ranges::out_value_result

Otherwise this looks ready to go in, thanks.


+#endif // __glibcxx_ranges_iota
+
#if __cplusplus >= 201402L
# include 
# include 
@@ -726,6 +730,40 @@ namespace __detail
  /// @} group numeric_ops
#endif // C++17

+namespace ranges
+{
+#if __glibcxx_ranges_iota >= 202202L // C++ >= 23
+
+  template
+  using iota_result = out_value_result<_Out, _Tp>;
+
+  struct __iota_fn
+  {
+template _Sent, 
weakly_incrementable _Tp>
+  requires indirectly_writable<_Out, const _Tp&>
+  constexpr iota_result<_Out, _Tp>
+  operator()(_Out __first, _Sent __last, _Tp __value) const
+  {
+   while (__first != __last)
+ {
+   *__first = static_cast(__value);
+   ++__first;
+   ++__value;
+ }
+   return {std::move(__first), std::move(__value)};
+  }
+
+template _Range>
+  constexpr iota_result, _Tp>
+  operator()(_Range&& __r, _Tp 

[PATCH] Add config file so b4 uses inbox.sourceware.org automatically

2024-05-23 Thread Jonathan Wakely
It looks like my patch[1] to make b4 figure this out automagically won't
be accepted, so this makes it work for GCC. A similar commit could be
done for each project hosted on sourceware.org if desired.

[1] 
https://lore.kernel.org/tools/20240523143752.385810-1-jwak...@redhat.com/T/#u

OK for trunk?

-- >8 --

This makes b4 use inbox.sourceware.org instead of the default host
lore.kernel.org, so that every b4 user doesn't have to configure this
themselves.

ChangeLog:

* .b4-config: New file.
---
 .b4-config | 3 +++
 1 file changed, 3 insertions(+)
 create mode 100644 .b4-config

diff --git a/.b4-config b/.b4-config
new file mode 100644
index 000..d5ba8e08446
--- /dev/null
+++ b/.b4-config
@@ -0,0 +1,3 @@
+[b4]
+midmask = https://inbox.sourceware.org/%s
+linkmask = https://inbox.sourceware.org/%s
-- 
2.45.1



Re: [PATCH] Avoid vector -Wfree-nonheap-object warnings

2024-05-23 Thread Jonathan Wakely

On 23/05/24 06:55 +0200, François Dumont wrote:

As explained in this email:

https://gcc.gnu.org/pipermail/libstdc++/2024-April/058552.html

I experimented -Wfree-nonheap-object because of my enhancements on algos.

So here is a patch to extend the usage of the _Guard type to other 
parts of vector.


Nice, that fixes the warning you were seeing?

We recently got a bug report about -Wfree-nonheap-object in
std::vector, but that is coming from _M_realloc_append which already
uses the RAII guard :-(
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115016


    libstdc++: Use RAII to replace try/catch blocks

    Move _Guard into std::vector declaration and use it to guard all 
calls to

    vector _M_allocate.

    Doing so the compiler has more visibility on what is done with the 
pointers

    and do not raise anymore the -Wfree-nonheap-object warning.

    libstdc++-v3/ChangeLog:

    * include/bits/vector.tcc (_Guard): Move...
    * include/bits/stl_vector.h: ...here.
    (_M_allocate_and_copy): Use latter.
    (_M_initialize_dispatch): Likewise and set _M_finish first 
from the result

    of __uninitialize_fill_n_a that can throw.
    (_M_range_initialize): Likewise.

Tested under Linux x86_64, ok to commit ?

François




diff --git a/libstdc++-v3/include/bits/stl_vector.h 
b/libstdc++-v3/include/bits/stl_vector.h
index 31169711a48..4ea74e3339a 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -1607,6 +1607,39 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
  clear() _GLIBCXX_NOEXCEPT
  { _M_erase_at_end(this->_M_impl._M_start); }

+private:
+  // RAII guard for allocated storage.
+  struct _Guard


If it's being defined at class scope instead of locally in a member
function, I think a better name would be good. Maybe _Ptr_guard or
_Dealloc_guard or something.


+  {
+   pointer _M_storage; // Storage to deallocate
+   size_type _M_len;
+   _Base& _M_vect;
+
+   _GLIBCXX20_CONSTEXPR
+   _Guard(pointer __s, size_type __l, _Base& __vect)
+   : _M_storage(__s), _M_len(__l), _M_vect(__vect)
+   { }
+
+   _GLIBCXX20_CONSTEXPR
+   ~_Guard()
+   {
+ if (_M_storage)
+   _M_vect._M_deallocate(_M_storage, _M_len);
+   }
+
+   _GLIBCXX20_CONSTEXPR
+   pointer
+   _M_release()
+   {
+ pointer __res = _M_storage;
+ _M_storage = 0;


I don't think the NullablePointer requirements include assigning 0,
only from nullptr, which isn't valid in C++98.

https://en.cppreference.com/w/cpp/named_req/NullablePointer

Please use _M_storage = pointer() instead.


+ return __res;
+   }
+
+  private:
+   _Guard(const _Guard&);
+  };
+
protected:
  /**
   *  Memory expansion handler.  Uses the member allocation function to
@@ -1618,18 +1651,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_M_allocate_and_copy(size_type __n,
 _ForwardIterator __first, _ForwardIterator __last)
{
- pointer __result = this->_M_allocate(__n);
- __try
-   {
- std::__uninitialized_copy_a(__first, __last, __result,
- _M_get_Tp_allocator());
- return __result;
-   }
- __catch(...)
-   {
- _M_deallocate(__result, __n);
- __throw_exception_again;
-   }
+ _Guard __guard(this->_M_allocate(__n), __n, *this);
+ std::__uninitialized_copy_a
+   (__first, __last, __guard._M_storage, _M_get_Tp_allocator());
+ return __guard._M_release();
}


@@ -1642,13 +1667,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
  // 438. Ambiguity in the "do the right thing" clause
  template
void
-   _M_initialize_dispatch(_Integer __n, _Integer __value, __true_type)
+   _M_initialize_dispatch(_Integer __int_n, _Integer __value, __true_type)
{
- this->_M_impl._M_start = _M_allocate(_S_check_init_len(
-   static_cast(__n), _M_get_Tp_allocator()));
- this->_M_impl._M_end_of_storage =
-   this->_M_impl._M_start + static_cast(__n);
- _M_fill_initialize(static_cast(__n), __value);


Please fix the comment on _M_fill_initialize if you're removing the
use of it here.


+ const size_type __n = static_cast(__int_n);
+ _Guard __guard(_M_allocate(_S_check_init_len(
+   __n, _M_get_Tp_allocator())), __n, *this);


I think this would be easier to read if the _S_check_init_len call was
done first, and maybe the allocation too, since we are going to need a
local __start later anyway. So maybe like this:

  template
void
_M_initialize_dispatch(_Integer __ni, _Integer __value, __true_type)
{
  const size_type __n = static_cast(__ni);
  pointer __start = _M_allocate(_S_check_init_len(__n),

[committed] libstdc++: Fix effects of combining locales [PR108323]

2024-05-22 Thread Jonathan Wakely
Tested x86_64-linux. Pushed to trunk.

-- >8 --

This fixes a bug in locale::combine where we fail to meet the standard's
requirement that the result is unnamed. It also implements two library
issues related to the names of combined locales (2295 and 3676).

libstdc++-v3/ChangeLog:

PR libstdc++/108323
* include/bits/locale_classes.tcc (locale(const locale&, Facet*)):
Return a copy of the first argument when the facet pointer is
null, as per LWG 2295.
(locale::combine): Ensure the result is unnamed.
* src/c++11/localename.cc (_M_replace_categories): Ignore
whether the second locale has a name when cat == none, as per
LWG 3676.
* src/c++98/locale.cc (_M_install_facet): Use __builtin_expect
to predict that the facet pointer is non-null.
* testsuite/22_locale/locale/cons/names.cc: New test.
---
 libstdc++-v3/include/bits/locale_classes.tcc  | 13 +++-
 libstdc++-v3/src/c++11/localename.cc  |  4 +-
 libstdc++-v3/src/c++98/locale.cc  |  2 +-
 .../testsuite/22_locale/locale/cons/names.cc  | 61 +++
 4 files changed, 77 insertions(+), 3 deletions(-)
 create mode 100644 libstdc++-v3/testsuite/22_locale/locale/cons/names.cc

diff --git a/libstdc++-v3/include/bits/locale_classes.tcc 
b/libstdc++-v3/include/bits/locale_classes.tcc
index 63097582dec..00eeb7dd9f8 100644
--- a/libstdc++-v3/include/bits/locale_classes.tcc
+++ b/libstdc++-v3/include/bits/locale_classes.tcc
@@ -44,6 +44,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 locale::
 locale(const locale& __other, _Facet* __f)
 {
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // 2295. Locale name when the provided Facet is a nullptr
+  if (__builtin_expect(!__f, 0))
+   {
+ _M_impl = __other._M_impl;
+ _M_impl->_M_add_reference();
+ return;
+   }
+
   _M_impl = new _Impl(*__other._M_impl, 1);
 
   __try
@@ -72,6 +81,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  __tmp->_M_remove_reference();
  __throw_exception_again;
}
+  delete[] __tmp->_M_names[0];
+  __tmp->_M_names[0] = 0;   // Unnamed.
   return locale(__tmp);
 }
 
@@ -163,7 +174,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   */
   template
 inline bool
-has_facet(const locale& __loc) throw()
+has_facet(const locale& __loc) _GLIBCXX_USE_NOEXCEPT
 {
 #if __cplusplus >= 201103L
   static_assert(__is_base_of(locale::facet, _Facet),
diff --git a/libstdc++-v3/src/c++11/localename.cc 
b/libstdc++-v3/src/c++11/localename.cc
index cde94ec6e19..909cf4c66d3 100644
--- a/libstdc++-v3/src/c++11/localename.cc
+++ b/libstdc++-v3/src/c++11/localename.cc
@@ -326,7 +326,9 @@ const int num_facets = (
   _M_replace_categories(const _Impl* __imp, category __cat)
   {
 category __mask = 1;
-if (!_M_names[0] || !__imp->_M_names[0])
+// _GLIBCXX_RESOLVE_LIB_DEFECTS
+// 3676. Name of locale composed using std::locale::none
+if (!_M_names[0] || (__cat != none && !__imp->_M_names[0]))
   {
if (_M_names[0])
  {
diff --git a/libstdc++-v3/src/c++98/locale.cc b/libstdc++-v3/src/c++98/locale.cc
index 3749408115e..0e7533e1e15 100644
--- a/libstdc++-v3/src/c++98/locale.cc
+++ b/libstdc++-v3/src/c++98/locale.cc
@@ -323,7 +323,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   locale::_Impl::
   _M_install_facet(const locale::id* __idp, const facet* __fp)
   {
-if (__fp)
+if (__builtin_expect(__fp != 0, 1))
   {
size_t __index = __idp->_M_id();
 
diff --git a/libstdc++-v3/testsuite/22_locale/locale/cons/names.cc 
b/libstdc++-v3/testsuite/22_locale/locale/cons/names.cc
new file mode 100644
index 000..2a9cfe4c14d
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/locale/cons/names.cc
@@ -0,0 +1,61 @@
+// { dg-do run }
+
+#include 
+#include 
+
+void
+test_pr108323()
+{
+  std::locale named = std::locale::classic();
+  std::locale unnamed = named.combine >(named);
+
+  // Bug libstdc++/108323 - combine does not change the locale name
+  VERIFY( unnamed.name() == "*" );
+}
+
+void
+test_lwg2295()
+{
+  std::locale named = std::locale::classic();
+  std::locale unnamed(named, ::use_facet >(named));
+  VERIFY( unnamed.name() == "*" );
+
+  // LWG 2295. Locale name when the provided Facet is a nullptr
+  std::locale loc(named, (std::ctype*)0);
+  VERIFY( loc.name() != "*" );
+  VERIFY( loc.name() == named.name() );
+}
+
+void
+test_lwg3676()
+{
+  std::locale named = std::locale::classic();
+  std::locale unnamed = named.combine >(named);
+  std::locale combo;
+
+  // LWG 3676. Name of locale composed using std::locale::none
+
+  combo = std::locale(named, named, std::locale::numeric);
+  VERIFY( combo.name() != "*" );
+  combo = std::locale(named, named, std::locale::none);
+  VERIFY( combo.name() != "*" );
+  combo = std::locale(named, unnamed, std::locale::numeric);
+  VERIFY( combo.name() == "*" );
+  combo = std::locale(named, unnamed, std::locale::none);
+  VERIFY( 

[committed] libstdc++: Add [[nodiscard]] to some std::locale functions

2024-05-22 Thread Jonathan Wakely
Tested x86_64-linux. Pushed to trunk.

-- >8 --

libstdc++-v3/ChangeLog:

* include/bits/locale_classes.h (locale::combine)
(locale::name, locale::operator==, locale::operator!=)
(locale::operator(), locale::classic): Add nodiscard
attribute.
* include/bits/locale_classes.tcc (has_facet, use_facet):
Likewise.
* testsuite/22_locale/locale/cons/12438.cc: Add dg-warning for
nodiscard diagnostic.
* testsuite/22_locale/locale/cons/2.cc: Cast use_facet
expression to void, to suppress diagnostic.
* testsuite/22_locale/locale/cons/unicode.cc: Likewise.
* testsuite/22_locale/locale/operations/2.cc: Add dg-warning.
---
 libstdc++-v3/include/bits/locale_classes.h  | 7 ++-
 libstdc++-v3/include/bits/locale_classes.tcc| 2 ++
 libstdc++-v3/testsuite/22_locale/locale/cons/12438.cc   | 2 +-
 libstdc++-v3/testsuite/22_locale/locale/cons/2.cc   | 2 +-
 libstdc++-v3/testsuite/22_locale/locale/cons/unicode.cc | 2 +-
 libstdc++-v3/testsuite/22_locale/locale/operations/2.cc | 2 +-
 6 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/libstdc++-v3/include/bits/locale_classes.h 
b/libstdc++-v3/include/bits/locale_classes.h
index a2e94217006..50a748066f1 100644
--- a/libstdc++-v3/include/bits/locale_classes.h
+++ b/libstdc++-v3/include/bits/locale_classes.h
@@ -240,6 +240,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  *  @throw  std::runtime_error if __other has no facet of type _Facet.
 */
 template
+  _GLIBCXX_NODISCARD
   locale
   combine(const locale& __other) const;
 
@@ -248,7 +249,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  *  @brief  Return locale name.
  *  @return  Locale name or "*" if unnamed.
 */
-_GLIBCXX_DEFAULT_ABI_TAG
+_GLIBCXX_NODISCARD _GLIBCXX_DEFAULT_ABI_TAG
 string
 name() const;
 
@@ -269,6 +270,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  *  @return  True if other and this refer to the same locale instance, are
  *  copies, or have the same name.  False otherwise.
 */
+_GLIBCXX_NODISCARD
 bool
 operator==(const locale& __other) const throw();
 
@@ -279,6 +281,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  *  @param  __other  The locale to compare against.
  *  @return  ! (*this == __other)
 */
+_GLIBCXX_NODISCARD
 bool
 operator!=(const locale& __other) const throw()
 { return !(this->operator==(__other)); }
@@ -300,6 +303,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  *  @return  True if collate<_Char> facet compares __s1 < __s2, else false.
 */
 template
+  _GLIBCXX_NODISCARD
   bool
   operator()(const basic_string<_Char, _Traits, _Alloc>& __s1,
 const basic_string<_Char, _Traits, _Alloc>& __s2) const;
@@ -321,6 +325,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 /**
  *  @brief  Return reference to the C locale.
 */
+_GLIBCXX_NODISCARD
 static const locale&
 classic();
 
diff --git a/libstdc++-v3/include/bits/locale_classes.tcc 
b/libstdc++-v3/include/bits/locale_classes.tcc
index 00eeb7dd9f8..c79574e58de 100644
--- a/libstdc++-v3/include/bits/locale_classes.tcc
+++ b/libstdc++-v3/include/bits/locale_classes.tcc
@@ -173,6 +173,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  @return  true if @p __loc contains a facet of type _Facet, else false.
   */
   template
+_GLIBCXX_NODISCARD
 inline bool
 has_facet(const locale& __loc) _GLIBCXX_USE_NOEXCEPT
 {
@@ -202,6 +203,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wdangling-reference"
   template
+_GLIBCXX_NODISCARD
 inline const _Facet&
 use_facet(const locale& __loc)
 {
diff --git a/libstdc++-v3/testsuite/22_locale/locale/cons/12438.cc 
b/libstdc++-v3/testsuite/22_locale/locale/cons/12438.cc
index 7ff3a487745..4838e1ba693 100644
--- a/libstdc++-v3/testsuite/22_locale/locale/cons/12438.cc
+++ b/libstdc++-v3/testsuite/22_locale/locale/cons/12438.cc
@@ -45,7 +45,7 @@ void test01(int iters)
  locale loc2 = locale("");
  VERIFY( !has_facet(loc2) );
  
- loc1.combine(loc2);
+ loc1.combine(loc2); // { dg-warning "nodiscard" "" { target 
c++17 } }
  VERIFY( false );
}
   catch (std::runtime_error&)
diff --git a/libstdc++-v3/testsuite/22_locale/locale/cons/2.cc 
b/libstdc++-v3/testsuite/22_locale/locale/cons/2.cc
index 12478dbfdc2..dce150effea 100644
--- a/libstdc++-v3/testsuite/22_locale/locale/cons/2.cc
+++ b/libstdc++-v3/testsuite/22_locale/locale/cons/2.cc
@@ -68,7 +68,7 @@ void test01()
 { VERIFY( false ); }
 
   try 
-{ use_facet(loc02); }
+{ (void) use_facet(loc02); }
   catch(bad_cast& obj)
 { VERIFY( true ); }
   catch(...)
diff --git a/libstdc++-v3/testsuite/22_locale/locale/cons/unicode.cc 
b/libstdc++-v3/testsuite/22_locale/locale/cons/unicode.cc
index 24af4142cd9..98d744de91e 100644
--- 

[gcc r15-782] libstdc++: Add [[nodiscard]] to some std::locale functions

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

commit r15-782-gfd1a674ff5f37e74fbbdcdb85d78399e963eb401
Author: Jonathan Wakely 
Date:   Wed May 22 18:38:36 2024 +0100

libstdc++: Add [[nodiscard]] to some std::locale functions

libstdc++-v3/ChangeLog:

* include/bits/locale_classes.h (locale::combine)
(locale::name, locale::operator==, locale::operator!=)
(locale::operator(), locale::classic): Add nodiscard
attribute.
* include/bits/locale_classes.tcc (has_facet, use_facet):
Likewise.
* testsuite/22_locale/locale/cons/12438.cc: Add dg-warning for
nodiscard diagnostic.
* testsuite/22_locale/locale/cons/2.cc: Cast use_facet
expression to void, to suppress diagnostic.
* testsuite/22_locale/locale/cons/unicode.cc: Likewise.
* testsuite/22_locale/locale/operations/2.cc: Add dg-warning.

Diff:
---
 libstdc++-v3/include/bits/locale_classes.h  | 7 ++-
 libstdc++-v3/include/bits/locale_classes.tcc| 2 ++
 libstdc++-v3/testsuite/22_locale/locale/cons/12438.cc   | 2 +-
 libstdc++-v3/testsuite/22_locale/locale/cons/2.cc   | 2 +-
 libstdc++-v3/testsuite/22_locale/locale/cons/unicode.cc | 2 +-
 libstdc++-v3/testsuite/22_locale/locale/operations/2.cc | 2 +-
 6 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/libstdc++-v3/include/bits/locale_classes.h 
b/libstdc++-v3/include/bits/locale_classes.h
index a2e94217006..50a748066f1 100644
--- a/libstdc++-v3/include/bits/locale_classes.h
+++ b/libstdc++-v3/include/bits/locale_classes.h
@@ -240,6 +240,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  *  @throw  std::runtime_error if __other has no facet of type _Facet.
 */
 template
+  _GLIBCXX_NODISCARD
   locale
   combine(const locale& __other) const;
 
@@ -248,7 +249,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  *  @brief  Return locale name.
  *  @return  Locale name or "*" if unnamed.
 */
-_GLIBCXX_DEFAULT_ABI_TAG
+_GLIBCXX_NODISCARD _GLIBCXX_DEFAULT_ABI_TAG
 string
 name() const;
 
@@ -269,6 +270,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  *  @return  True if other and this refer to the same locale instance, are
  *  copies, or have the same name.  False otherwise.
 */
+_GLIBCXX_NODISCARD
 bool
 operator==(const locale& __other) const throw();
 
@@ -279,6 +281,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  *  @param  __other  The locale to compare against.
  *  @return  ! (*this == __other)
 */
+_GLIBCXX_NODISCARD
 bool
 operator!=(const locale& __other) const throw()
 { return !(this->operator==(__other)); }
@@ -300,6 +303,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  *  @return  True if collate<_Char> facet compares __s1 < __s2, else false.
 */
 template
+  _GLIBCXX_NODISCARD
   bool
   operator()(const basic_string<_Char, _Traits, _Alloc>& __s1,
 const basic_string<_Char, _Traits, _Alloc>& __s2) const;
@@ -321,6 +325,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 /**
  *  @brief  Return reference to the C locale.
 */
+_GLIBCXX_NODISCARD
 static const locale&
 classic();
 
diff --git a/libstdc++-v3/include/bits/locale_classes.tcc 
b/libstdc++-v3/include/bits/locale_classes.tcc
index 00eeb7dd9f8..c79574e58de 100644
--- a/libstdc++-v3/include/bits/locale_classes.tcc
+++ b/libstdc++-v3/include/bits/locale_classes.tcc
@@ -173,6 +173,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  @return  true if @p __loc contains a facet of type _Facet, else false.
   */
   template
+_GLIBCXX_NODISCARD
 inline bool
 has_facet(const locale& __loc) _GLIBCXX_USE_NOEXCEPT
 {
@@ -202,6 +203,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wdangling-reference"
   template
+_GLIBCXX_NODISCARD
 inline const _Facet&
 use_facet(const locale& __loc)
 {
diff --git a/libstdc++-v3/testsuite/22_locale/locale/cons/12438.cc 
b/libstdc++-v3/testsuite/22_locale/locale/cons/12438.cc
index 7ff3a487745..4838e1ba693 100644
--- a/libstdc++-v3/testsuite/22_locale/locale/cons/12438.cc
+++ b/libstdc++-v3/testsuite/22_locale/locale/cons/12438.cc
@@ -45,7 +45,7 @@ void test01(int iters)
  locale loc2 = locale("");
  VERIFY( !has_facet(loc2) );
  
- loc1.combine(loc2);
+ loc1.combine(loc2); // { dg-warning "nodiscard" "" { target 
c++17 } }
  VERIFY( false );
}
   catch (std::runtime_error&)
diff --git a/libstdc++-v3/testsuite/22_locale/locale/cons/2.cc 
b/libstdc++-v3/testsuite/22_locale/locale/cons/2.cc
index 12478dbfdc2..dce150effea 100644
--- a/libstdc++-v3/testsuite/22_locale/locale/cons/2.cc
+++ b/libstdc++-v3/testsuite/22_locale/locale/cons/2.cc
@@ -68,7 +

[gcc r15-781] libstdc++: Fix effects of combining locales [PR108323]

2024-05-22 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:947a9c801e818f412ad4c669a49297c3512b3a6e

commit r15-781-g947a9c801e818f412ad4c669a49297c3512b3a6e
Author: Jonathan Wakely 
Date:   Tue Jan 30 14:48:28 2024 +

libstdc++: Fix effects of combining locales [PR108323]

This fixes a bug in locale::combine where we fail to meet the standard's
requirement that the result is unnamed. It also implements two library
issues related to the names of combined locales (2295 and 3676).

libstdc++-v3/ChangeLog:

PR libstdc++/108323
* include/bits/locale_classes.tcc (locale(const locale&, Facet*)):
Return a copy of the first argument when the facet pointer is
null, as per LWG 2295.
(locale::combine): Ensure the result is unnamed.
* src/c++11/localename.cc (_M_replace_categories): Ignore
whether the second locale has a name when cat == none, as per
LWG 3676.
* src/c++98/locale.cc (_M_install_facet): Use __builtin_expect
to predict that the facet pointer is non-null.
* testsuite/22_locale/locale/cons/names.cc: New test.

Diff:
---
 libstdc++-v3/include/bits/locale_classes.tcc   | 13 -
 libstdc++-v3/src/c++11/localename.cc   |  4 +-
 libstdc++-v3/src/c++98/locale.cc   |  2 +-
 .../testsuite/22_locale/locale/cons/names.cc   | 61 ++
 4 files changed, 77 insertions(+), 3 deletions(-)

diff --git a/libstdc++-v3/include/bits/locale_classes.tcc 
b/libstdc++-v3/include/bits/locale_classes.tcc
index 63097582dec..00eeb7dd9f8 100644
--- a/libstdc++-v3/include/bits/locale_classes.tcc
+++ b/libstdc++-v3/include/bits/locale_classes.tcc
@@ -44,6 +44,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 locale::
 locale(const locale& __other, _Facet* __f)
 {
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // 2295. Locale name when the provided Facet is a nullptr
+  if (__builtin_expect(!__f, 0))
+   {
+ _M_impl = __other._M_impl;
+ _M_impl->_M_add_reference();
+ return;
+   }
+
   _M_impl = new _Impl(*__other._M_impl, 1);
 
   __try
@@ -72,6 +81,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  __tmp->_M_remove_reference();
  __throw_exception_again;
}
+  delete[] __tmp->_M_names[0];
+  __tmp->_M_names[0] = 0;   // Unnamed.
   return locale(__tmp);
 }
 
@@ -163,7 +174,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   */
   template
 inline bool
-has_facet(const locale& __loc) throw()
+has_facet(const locale& __loc) _GLIBCXX_USE_NOEXCEPT
 {
 #if __cplusplus >= 201103L
   static_assert(__is_base_of(locale::facet, _Facet),
diff --git a/libstdc++-v3/src/c++11/localename.cc 
b/libstdc++-v3/src/c++11/localename.cc
index cde94ec6e19..909cf4c66d3 100644
--- a/libstdc++-v3/src/c++11/localename.cc
+++ b/libstdc++-v3/src/c++11/localename.cc
@@ -326,7 +326,9 @@ const int num_facets = (
   _M_replace_categories(const _Impl* __imp, category __cat)
   {
 category __mask = 1;
-if (!_M_names[0] || !__imp->_M_names[0])
+// _GLIBCXX_RESOLVE_LIB_DEFECTS
+// 3676. Name of locale composed using std::locale::none
+if (!_M_names[0] || (__cat != none && !__imp->_M_names[0]))
   {
if (_M_names[0])
  {
diff --git a/libstdc++-v3/src/c++98/locale.cc b/libstdc++-v3/src/c++98/locale.cc
index 3749408115e..0e7533e1e15 100644
--- a/libstdc++-v3/src/c++98/locale.cc
+++ b/libstdc++-v3/src/c++98/locale.cc
@@ -323,7 +323,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   locale::_Impl::
   _M_install_facet(const locale::id* __idp, const facet* __fp)
   {
-if (__fp)
+if (__builtin_expect(__fp != 0, 1))
   {
size_t __index = __idp->_M_id();
 
diff --git a/libstdc++-v3/testsuite/22_locale/locale/cons/names.cc 
b/libstdc++-v3/testsuite/22_locale/locale/cons/names.cc
new file mode 100644
index 000..2a9cfe4c14d
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/locale/cons/names.cc
@@ -0,0 +1,61 @@
+// { dg-do run }
+
+#include 
+#include 
+
+void
+test_pr108323()
+{
+  std::locale named = std::locale::classic();
+  std::locale unnamed = named.combine >(named);
+
+  // Bug libstdc++/108323 - combine does not change the locale name
+  VERIFY( unnamed.name() == "*" );
+}
+
+void
+test_lwg2295()
+{
+  std::locale named = std::locale::classic();
+  std::locale unnamed(named, ::use_facet >(named));
+  VERIFY( unnamed.name() == "*" );
+
+  // LWG 2295. Locale name when the provided Facet is a nullptr
+  std::locale loc(named, (std::ctype*)0);
+  VERIFY( loc.name() != "*" );
+  VERIFY( loc.name() == named.name() );
+}
+
+void
+test_lwg3676()
+{
+  std::locale named = std::locale::classic();
+  std::locale unnamed = named.combine >(named);
+  std::locale combo;
+
+  // LWG 3676. Name of locale composed using std::locale::none
+
+  combo = std::locale(named, named, std::

[committed] libstdc++: Guard use of sized deallocation [PR114940]

2024-05-22 Thread Jonathan Wakely
Tested x86_64-linux. Pushed to trunk. Backport needed too.

-- >8 --

Clang does not enable -fsized-deallocation by default, which means it
can't compile our  and  headers.

Make the __cpp_lib_generator macro depend on the compiler-defined
__cpp_sized_deallocation macro, and change  to use unsized
deallocation when __cpp_sized_deallocation isn't defined.

libstdc++-v3/ChangeLog:

PR libstdc++/114940
* include/bits/version.def (generator): Depend on
__cpp_sized_deallocation.
* include/bits/version.h: Regenerate.
* include/std/stacktrace (_GLIBCXX_SIZED_DELETE): New macro.
(basic_stacktrace::_Impl::_M_deallocate): Use it.
---
 libstdc++-v3/include/bits/version.def |  2 +-
 libstdc++-v3/include/bits/version.h   |  2 +-
 libstdc++-v3/include/std/stacktrace   | 13 +++--
 3 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/libstdc++-v3/include/bits/version.def 
b/libstdc++-v3/include/bits/version.def
index f0ba4f2bb3d..5cbc9d1a8d8 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -1651,7 +1651,7 @@ ftms = {
   values = {
 v = 202207;
 cxxmin = 23;
-extra_cond = "__glibcxx_coroutine";
+extra_cond = "__glibcxx_coroutine && __cpp_sized_deallocation";
   };
 };
 
diff --git a/libstdc++-v3/include/bits/version.h 
b/libstdc++-v3/include/bits/version.h
index f30f51dcedc..164ebed4983 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -1834,7 +1834,7 @@
 #undef __glibcxx_want_forward_like
 
 #if !defined(__cpp_lib_generator)
-# if (__cplusplus >= 202100L) && (__glibcxx_coroutine)
+# if (__cplusplus >= 202100L) && (__glibcxx_coroutine && 
__cpp_sized_deallocation)
 #  define __glibcxx_generator 202207L
 #  if defined(__glibcxx_want_all) || defined(__glibcxx_want_generator)
 #   define __cpp_lib_generator 202207L
diff --git a/libstdc++-v3/include/std/stacktrace 
b/libstdc++-v3/include/std/stacktrace
index d217d63af3b..962dbed7a41 100644
--- a/libstdc++-v3/include/std/stacktrace
+++ b/libstdc++-v3/include/std/stacktrace
@@ -551,6 +551,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #else
 # define _GLIBCXX_OPERATOR_NEW ::operator new
 # define _GLIBCXX_OPERATOR_DELETE ::operator delete
+#endif
+
+#if __cpp_sized_deallocation
+# define _GLIBCXX_SIZED_DELETE(T, p, n) \
+  _GLIBCXX_OPERATOR_DELETE((p), (n) * sizeof(T))
+#else
+# define _GLIBCXX_SIZED_DELETE(T, p, n) _GLIBCXX_OPERATOR_DELETE(p)
 #endif
 
// Precondition: _M_frames == nullptr && __n != 0
@@ -592,8 +599,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  if (_M_capacity)
{
  if constexpr (is_same_v>)
-   _GLIBCXX_OPERATOR_DELETE (static_cast(_M_frames),
- _M_capacity * sizeof(value_type));
+   _GLIBCXX_SIZED_DELETE(value_type,
+ static_cast(_M_frames),
+ _M_capacity);
  else
__alloc.deallocate(_M_frames, _M_capacity);
  _M_frames = nullptr;
@@ -601,6 +609,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
}
 
+#undef _GLIBCXX_SIZED_DELETE
 #undef _GLIBCXX_OPERATOR_DELETE
 #undef _GLIBCXX_OPERATOR_NEW
 
-- 
2.45.1



[gcc r15-780] libstdc++: Guard use of sized deallocation [PR114940]

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

commit r15-780-gb2fdd508d7e63158e9d2a6dd04f901d02900def3
Author: Jonathan Wakely 
Date:   Wed May 22 10:32:43 2024 +0100

libstdc++: Guard use of sized deallocation [PR114940]

Clang does not enable -fsized-deallocation by default, which means it
can't compile our  and  headers.

Make the __cpp_lib_generator macro depend on the compiler-defined
__cpp_sized_deallocation macro, and change  to use unsized
deallocation when __cpp_sized_deallocation isn't defined.

libstdc++-v3/ChangeLog:

PR libstdc++/114940
* include/bits/version.def (generator): Depend on
__cpp_sized_deallocation.
* include/bits/version.h: Regenerate.
* include/std/stacktrace (_GLIBCXX_SIZED_DELETE): New macro.
(basic_stacktrace::_Impl::_M_deallocate): Use it.

Diff:
---
 libstdc++-v3/include/bits/version.def |  2 +-
 libstdc++-v3/include/bits/version.h   |  2 +-
 libstdc++-v3/include/std/stacktrace   | 13 +++--
 3 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/libstdc++-v3/include/bits/version.def 
b/libstdc++-v3/include/bits/version.def
index f0ba4f2bb3d..5cbc9d1a8d8 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -1651,7 +1651,7 @@ ftms = {
   values = {
 v = 202207;
 cxxmin = 23;
-extra_cond = "__glibcxx_coroutine";
+extra_cond = "__glibcxx_coroutine && __cpp_sized_deallocation";
   };
 };
 
diff --git a/libstdc++-v3/include/bits/version.h 
b/libstdc++-v3/include/bits/version.h
index f30f51dcedc..164ebed4983 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -1834,7 +1834,7 @@
 #undef __glibcxx_want_forward_like
 
 #if !defined(__cpp_lib_generator)
-# if (__cplusplus >= 202100L) && (__glibcxx_coroutine)
+# if (__cplusplus >= 202100L) && (__glibcxx_coroutine && 
__cpp_sized_deallocation)
 #  define __glibcxx_generator 202207L
 #  if defined(__glibcxx_want_all) || defined(__glibcxx_want_generator)
 #   define __cpp_lib_generator 202207L
diff --git a/libstdc++-v3/include/std/stacktrace 
b/libstdc++-v3/include/std/stacktrace
index d217d63af3b..962dbed7a41 100644
--- a/libstdc++-v3/include/std/stacktrace
+++ b/libstdc++-v3/include/std/stacktrace
@@ -551,6 +551,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #else
 # define _GLIBCXX_OPERATOR_NEW ::operator new
 # define _GLIBCXX_OPERATOR_DELETE ::operator delete
+#endif
+
+#if __cpp_sized_deallocation
+# define _GLIBCXX_SIZED_DELETE(T, p, n) \
+  _GLIBCXX_OPERATOR_DELETE((p), (n) * sizeof(T))
+#else
+# define _GLIBCXX_SIZED_DELETE(T, p, n) _GLIBCXX_OPERATOR_DELETE(p)
 #endif
 
// Precondition: _M_frames == nullptr && __n != 0
@@ -592,8 +599,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  if (_M_capacity)
{
  if constexpr (is_same_v>)
-   _GLIBCXX_OPERATOR_DELETE (static_cast(_M_frames),
- _M_capacity * sizeof(value_type));
+   _GLIBCXX_SIZED_DELETE(value_type,
+ static_cast(_M_frames),
+ _M_capacity);
  else
__alloc.deallocate(_M_frames, _M_capacity);
  _M_frames = nullptr;
@@ -601,6 +609,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
}
 
+#undef _GLIBCXX_SIZED_DELETE
 #undef _GLIBCXX_OPERATOR_DELETE
 #undef _GLIBCXX_OPERATOR_NEW


[gcc r14-10232] libstdc++: Implement std::formatter without [PR115099]

2024-05-22 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:4896bb3199253dc350f8fb5ff63370310ca27ce2

commit r14-10232-g4896bb3199253dc350f8fb5ff63370310ca27ce2
Author: Jonathan Wakely 
Date:   Fri May 17 10:55:32 2024 +0100

libstdc++: Implement std::formatter without  
[PR115099]

The std::thread::id formatter uses std::basic_ostringstream without
including , which went unnoticed because the test for it uses
a stringstream to check the output is correct.

The fix implemented here is to stop using basic_ostringstream for
formatting thread::id and just use std::format instead.

As a drive-by fix, the formatter specialization is constrained to
require that the thread::id::native_handle_type can be formatted, to
avoid making the formatter ill-formed if the pthread_t type is not a
pointer or integer. Since non-void pointers can't be formatted, ensure
that we convert pointers to const void* for formatting. Make a similar
change to the existing operator<< overload so that in the unlikely case
that pthread_t is a typedef for char* we don't treat it as a
null-terminated string when inserting into a stream.

libstdc++-v3/ChangeLog:

PR libstdc++/115099
* include/bits/std_thread.h: Declare formatter as friend of
thread::id.
* include/std/thread (operator<<): Convert non-void pointers to
void pointers for output.
(formatter): Add constraint that thread::native_handle_type is a
pointer or integer.
(formatter::format): Reimplement without basic_ostringstream.
* testsuite/30_threads/thread/id/output.cc: Check output
compiles before  has been included.

(cherry picked from commit 1a5e4dd83788ea4c049d354d83ad58a6a3d747e6)

Diff:
---
 libstdc++-v3/include/bits/std_thread.h | 11 +-
 libstdc++-v3/include/std/thread| 43 +-
 .../testsuite/30_threads/thread/id/output.cc   | 21 ++-
 3 files changed, 63 insertions(+), 12 deletions(-)

diff --git a/libstdc++-v3/include/bits/std_thread.h 
b/libstdc++-v3/include/bits/std_thread.h
index 2d7df12650d..5817bfb29dd 100644
--- a/libstdc++-v3/include/bits/std_thread.h
+++ b/libstdc++-v3/include/bits/std_thread.h
@@ -53,6 +53,10 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
+#if __glibcxx_formatters
+  template class formatter;
+#endif
+
   /** @addtogroup threads
*  @{
*/
@@ -117,13 +121,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
friend basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __out, id __id);
+
+#if __glibcxx_formatters
+  friend formatter;
+  friend formatter;
+#endif
 };
 
   private:
 id _M_id;
 
 // _GLIBCXX_RESOLVE_LIB_DEFECTS
-// 2097.  packaged_task constructors should be constrained
+// 2097. packaged_task constructors should be constrained
 // 3039. Unnecessary decay in thread and packaged_task
 template
   using __not_same = __not_, thread>>;
diff --git a/libstdc++-v3/include/std/thread b/libstdc++-v3/include/std/thread
index 09ca3116e7f..e994d683bff 100644
--- a/libstdc++-v3/include/std/thread
+++ b/libstdc++-v3/include/std/thread
@@ -42,10 +42,6 @@
 # include  // std::stop_source, std::stop_token, std::nostopstate
 #endif
 
-#if __cplusplus > 202002L
-# include 
-#endif
-
 #include  // std::thread, get_id, yield
 #include  // std::this_thread::sleep_for, sleep_until
 
@@ -53,6 +49,10 @@
 #define __glibcxx_want_formatters
 #include 
 
+#if __cpp_lib_formatters
+# include 
+#endif
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -104,10 +104,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 inline basic_ostream<_CharT, _Traits>&
 operator<<(basic_ostream<_CharT, _Traits>& __out, thread::id __id)
 {
+  // Convert non-void pointers to const void* for formatted output.
+  using __output_type
+   = __conditional_t::value,
+ const void*,
+ thread::native_handle_type>;
+
   if (__id == thread::id())
return __out << "thread::id of a non-executing thread";
   else
-   return __out << __id._M_thread;
+   return __out << static_cast<__output_type>(__id._M_thread);
 }
   /// @}
 
@@ -287,8 +293,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif // __cpp_lib_jthread
 
 #ifdef __cpp_lib_formatters // C++ >= 23
-
   template
+requires is_pointer_v
+  || is_integral_v
 class formatter
 {
 public:
@@ -331,10 +338,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename basic_format_context<_Out, _CharT>::iterator
format(thread::id __id, basic_format_context<_Out, _CharT>& __fc) const
{
-

Re: [PATCH] libstdc++: Implement std::formatter without [PR115099]

2024-05-22 Thread Jonathan Wakely
Pushed to trunk. Backport to gcc-14 to follow.

On Fri, 17 May 2024 at 14:45, Jonathan Wakely  wrote:
>
> Does anybody see any issue with the drive-by fixes to constraint
> std::formatter to only work for pointers and integers (since
> we don't know how to format pthread_t if it's an arbitrary struct, for
> example), and to cast pointers to const void* for output (because if
> pthread_t is char* then writing it to a stream would be bad! and we
> don't want to allow users to overload operator<< for pointers to opaque
> structs, for example). I don't think this will change anything in
> practice for common targets, where pthread_t is either an integer or
> void*.
>
> Tested x86_64-linux.
>
> -- >8 --
>
> The std::thread::id formatter uses std::basic_ostringstream without
> including , which went unnoticed because the test for it uses
> a stringstream to check the output is correct.
>
> The fix implemented here is to stop using basic_ostringstream for
> formatting thread::id and just use std::format instead.
>
> As a drive-by fix, the formatter specialization is constrained to
> require that the thread::id::native_handle_type can be formatted, to
> avoid making the formatter ill-formed if the pthread_t type is not a
> pointer or integer. Since non-void pointers can't be formatted, ensure
> that we convert pointers to const void* for formatting. Make a similar
> change to the existing operator<< overload so that in the unlikely case
> that pthread_t is a typedef for char* we don't treat it as a
> null-terminated string when inserting into a stream.
>
> libstdc++-v3/ChangeLog:
>
> PR libstdc++/115099
> * include/bits/std_thread.h: Declare formatter as friend of
> thread::id.
> * include/std/thread (operator<<): Convert non-void pointers to
> void pointers for output.
> (formatter): Add constraint that thread::native_handle_type is a
> pointer or integer.
> (formatter::format): Reimplement without basic_ostringstream.
> * testsuite/30_threads/thread/id/output.cc: Check output
> compiles before  has been included.
> ---
>  libstdc++-v3/include/bits/std_thread.h| 11 -
>  libstdc++-v3/include/std/thread   | 43 ++-
>  .../testsuite/30_threads/thread/id/output.cc  | 21 -
>  3 files changed, 63 insertions(+), 12 deletions(-)
>
> diff --git a/libstdc++-v3/include/bits/std_thread.h 
> b/libstdc++-v3/include/bits/std_thread.h
> index 2d7df12650d..5817bfb29dd 100644
> --- a/libstdc++-v3/include/bits/std_thread.h
> +++ b/libstdc++-v3/include/bits/std_thread.h
> @@ -53,6 +53,10 @@ namespace std _GLIBCXX_VISIBILITY(default)
>  {
>  _GLIBCXX_BEGIN_NAMESPACE_VERSION
>
> +#if __glibcxx_formatters
> +  template class formatter;
> +#endif
> +
>/** @addtogroup threads
> *  @{
> */
> @@ -117,13 +121,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>template
> friend basic_ostream<_CharT, _Traits>&
> operator<<(basic_ostream<_CharT, _Traits>& __out, id __id);
> +
> +#if __glibcxx_formatters
> +  friend formatter;
> +  friend formatter;
> +#endif
>  };
>
>private:
>  id _M_id;
>
>  // _GLIBCXX_RESOLVE_LIB_DEFECTS
> -// 2097.  packaged_task constructors should be constrained
> +// 2097. packaged_task constructors should be constrained
>  // 3039. Unnecessary decay in thread and packaged_task
>  template
>using __not_same = __not_, thread>>;
> diff --git a/libstdc++-v3/include/std/thread b/libstdc++-v3/include/std/thread
> index 09ca3116e7f..e994d683bff 100644
> --- a/libstdc++-v3/include/std/thread
> +++ b/libstdc++-v3/include/std/thread
> @@ -42,10 +42,6 @@
>  # include  // std::stop_source, std::stop_token, std::nostopstate
>  #endif
>
> -#if __cplusplus > 202002L
> -# include 
> -#endif
> -
>  #include  // std::thread, get_id, yield
>  #include  // std::this_thread::sleep_for, 
> sleep_until
>
> @@ -53,6 +49,10 @@
>  #define __glibcxx_want_formatters
>  #include 
>
> +#if __cpp_lib_formatters
> +# include 
> +#endif
> +
>  namespace std _GLIBCXX_VISIBILITY(default)
>  {
>  _GLIBCXX_BEGIN_NAMESPACE_VERSION
> @@ -104,10 +104,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>  inline basic_ostream<_CharT, _Traits>&
>  operator<<(basic_ostream<_CharT, _Traits>& __out, thread::id __id)
>  {
> +  // Convert non-void pointers to const void* for formatted output.
> +  using __output_type
> +   = __conditional_t::value,
> + const void*,

[gcc r15-770] libstdc++: Implement std::formatter without [PR115099]

2024-05-22 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:1a5e4dd83788ea4c049d354d83ad58a6a3d747e6

commit r15-770-g1a5e4dd83788ea4c049d354d83ad58a6a3d747e6
Author: Jonathan Wakely 
Date:   Fri May 17 10:55:32 2024 +0100

libstdc++: Implement std::formatter without  
[PR115099]

The std::thread::id formatter uses std::basic_ostringstream without
including , which went unnoticed because the test for it uses
a stringstream to check the output is correct.

The fix implemented here is to stop using basic_ostringstream for
formatting thread::id and just use std::format instead.

As a drive-by fix, the formatter specialization is constrained to
require that the thread::id::native_handle_type can be formatted, to
avoid making the formatter ill-formed if the pthread_t type is not a
pointer or integer. Since non-void pointers can't be formatted, ensure
that we convert pointers to const void* for formatting. Make a similar
change to the existing operator<< overload so that in the unlikely case
that pthread_t is a typedef for char* we don't treat it as a
null-terminated string when inserting into a stream.

libstdc++-v3/ChangeLog:

PR libstdc++/115099
* include/bits/std_thread.h: Declare formatter as friend of
thread::id.
* include/std/thread (operator<<): Convert non-void pointers to
void pointers for output.
(formatter): Add constraint that thread::native_handle_type is a
pointer or integer.
(formatter::format): Reimplement without basic_ostringstream.
* testsuite/30_threads/thread/id/output.cc: Check output
compiles before  has been included.

Diff:
---
 libstdc++-v3/include/bits/std_thread.h | 11 +-
 libstdc++-v3/include/std/thread| 43 +-
 .../testsuite/30_threads/thread/id/output.cc   | 21 ++-
 3 files changed, 63 insertions(+), 12 deletions(-)

diff --git a/libstdc++-v3/include/bits/std_thread.h 
b/libstdc++-v3/include/bits/std_thread.h
index 2d7df12650d..5817bfb29dd 100644
--- a/libstdc++-v3/include/bits/std_thread.h
+++ b/libstdc++-v3/include/bits/std_thread.h
@@ -53,6 +53,10 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
+#if __glibcxx_formatters
+  template class formatter;
+#endif
+
   /** @addtogroup threads
*  @{
*/
@@ -117,13 +121,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
friend basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __out, id __id);
+
+#if __glibcxx_formatters
+  friend formatter;
+  friend formatter;
+#endif
 };
 
   private:
 id _M_id;
 
 // _GLIBCXX_RESOLVE_LIB_DEFECTS
-// 2097.  packaged_task constructors should be constrained
+// 2097. packaged_task constructors should be constrained
 // 3039. Unnecessary decay in thread and packaged_task
 template
   using __not_same = __not_, thread>>;
diff --git a/libstdc++-v3/include/std/thread b/libstdc++-v3/include/std/thread
index 09ca3116e7f..e994d683bff 100644
--- a/libstdc++-v3/include/std/thread
+++ b/libstdc++-v3/include/std/thread
@@ -42,10 +42,6 @@
 # include  // std::stop_source, std::stop_token, std::nostopstate
 #endif
 
-#if __cplusplus > 202002L
-# include 
-#endif
-
 #include  // std::thread, get_id, yield
 #include  // std::this_thread::sleep_for, sleep_until
 
@@ -53,6 +49,10 @@
 #define __glibcxx_want_formatters
 #include 
 
+#if __cpp_lib_formatters
+# include 
+#endif
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -104,10 +104,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 inline basic_ostream<_CharT, _Traits>&
 operator<<(basic_ostream<_CharT, _Traits>& __out, thread::id __id)
 {
+  // Convert non-void pointers to const void* for formatted output.
+  using __output_type
+   = __conditional_t::value,
+ const void*,
+ thread::native_handle_type>;
+
   if (__id == thread::id())
return __out << "thread::id of a non-executing thread";
   else
-   return __out << __id._M_thread;
+   return __out << static_cast<__output_type>(__id._M_thread);
 }
   /// @}
 
@@ -287,8 +293,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif // __cpp_lib_jthread
 
 #ifdef __cpp_lib_formatters // C++ >= 23
-
   template
+requires is_pointer_v
+  || is_integral_v
 class formatter
 {
 public:
@@ -331,10 +338,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename basic_format_context<_Out, _CharT>::iterator
format(thread::id __id, basic_format_context<_Out, _CharT>& __fc) const
{
- std::basic_ostringstream<_CharT> __os;
- __os << __id;
- 

[committed] libstdc++: Ensure std::variant relops convert to bool [PR115145]

2024-05-22 Thread Jonathan Wakely
Tested x86_64-linux. Pushed to trunk.

-- >8 --

Ensure that the result of comparing the variant alternatives is
converted to bool immediately rather than copied.

libstdc++-v3/ChangeLog:

PR libstdc++/115145
* include/std/variant (operator==, operator!=, operator<)
(operator<=, operator>, operator>=): Add trailing-return-type to
lambda expressions to trigger conversion to bool.
* testsuite/20_util/variant/relops/115145.cc: New test.
---
 libstdc++-v3/include/std/variant  | 63 ++-
 .../20_util/variant/relops/115145.cc  | 36 +++
 2 files changed, 71 insertions(+), 28 deletions(-)
 create mode 100644 libstdc++-v3/testsuite/20_util/variant/relops/115145.cc

diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant
index cfb4bcdbcc9..371cbb90f54 100644
--- a/libstdc++-v3/include/std/variant
+++ b/libstdc++-v3/include/std/variant
@@ -1271,10 +1271,11 @@ namespace __detail::__variant
 operator== [[nodiscard]] (const variant<_Types...>& __lhs,
  const variant<_Types...>& __rhs)
 {
-  return __detail::__variant::__compare(true, __lhs, __rhs,
-   [](auto&& __l, auto&& __r) {
- return __l == __r;
-   });
+  namespace __variant = __detail::__variant;
+  return __variant::__compare(true, __lhs, __rhs,
+ [](auto&& __l, auto&& __r) -> bool {
+   return __l == __r;
+ });
 }
 
   template
@@ -1286,10 +1287,11 @@ namespace __detail::__variant
 operator!= [[nodiscard]] (const variant<_Types...>& __lhs,
  const variant<_Types...>& __rhs)
 {
-  return __detail::__variant::__compare(true, __lhs, __rhs,
-   [](auto&& __l, auto&& __r) {
- return __l != __r;
-   });
+  namespace __variant = __detail::__variant;
+  return __variant::__compare(true, __lhs, __rhs,
+ [](auto&& __l, auto&& __r) -> bool {
+   return __l != __r;
+ });
 }
 
   template
@@ -1301,10 +1303,11 @@ namespace __detail::__variant
 operator< [[nodiscard]] (const variant<_Types...>& __lhs,
 const variant<_Types...>& __rhs)
 {
-  return __detail::__variant::__compare(true, __lhs, __rhs,
-   [](auto&& __l, auto&& __r) {
- return __l < __r;
-   });
+  namespace __variant = __detail::__variant;
+  return __variant::__compare(true, __lhs, __rhs,
+ [](auto&& __l, auto&& __r) -> bool {
+   return __l < __r;
+ });
 }
 
   template
@@ -1316,10 +1319,11 @@ namespace __detail::__variant
 operator<= [[nodiscard]] (const variant<_Types...>& __lhs,
  const variant<_Types...>& __rhs)
 {
-  return __detail::__variant::__compare(true, __lhs, __rhs,
-   [](auto&& __l, auto&& __r) {
- return __l <= __r;
-   });
+  namespace __variant = __detail::__variant;
+  return __variant::__compare(true, __lhs, __rhs,
+ [](auto&& __l, auto&& __r) -> bool {
+   return __l <= __r;
+ });
 }
 
   template
@@ -1331,10 +1335,11 @@ namespace __detail::__variant
 operator> [[nodiscard]] (const variant<_Types...>& __lhs,
 const variant<_Types...>& __rhs)
 {
-  return __detail::__variant::__compare(true, __lhs, __rhs,
-   [](auto&& __l, auto&& __r) {
- return __l > __r;
-   });
+  namespace __variant = __detail::__variant;
+  return __variant::__compare(true, __lhs, __rhs,
+ [](auto&& __l, auto&& __r) -> bool {
+   return __l > __r;
+ });
 }
 
   template
@@ -1346,10 +1351,11 @@ namespace __detail::__variant
 operator>= [[nodiscard]] (const variant<_Types...>& __lhs,
  const variant<_Types...>& __rhs)
 {
-  return __detail::__variant::__compare(true, __lhs, __rhs,
-   [](auto&& __l, auto&& __r) {
- return __l >= __r;
-  

[gcc r15-769] libstdc++: Ensure std::variant relops convert to bool [PR115145]

2024-05-22 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:b33f44ca6ce2dae7502ce138600e1631ffc9232c

commit r15-769-gb33f44ca6ce2dae7502ce138600e1631ffc9232c
Author: Jonathan Wakely 
Date:   Tue May 21 15:13:01 2024 +0100

libstdc++: Ensure std::variant relops convert to bool [PR115145]

Ensure that the result of comparing the variant alternatives is
converted to bool immediately rather than copied.

libstdc++-v3/ChangeLog:

PR libstdc++/115145
* include/std/variant (operator==, operator!=, operator<)
(operator<=, operator>, operator>=): Add trailing-return-type to
lambda expressions to trigger conversion to bool.
* testsuite/20_util/variant/relops/115145.cc: New test.

Diff:
---
 libstdc++-v3/include/std/variant   | 63 --
 .../testsuite/20_util/variant/relops/115145.cc | 36 +
 2 files changed, 71 insertions(+), 28 deletions(-)

diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant
index cfb4bcdbcc9..371cbb90f54 100644
--- a/libstdc++-v3/include/std/variant
+++ b/libstdc++-v3/include/std/variant
@@ -1271,10 +1271,11 @@ namespace __detail::__variant
 operator== [[nodiscard]] (const variant<_Types...>& __lhs,
  const variant<_Types...>& __rhs)
 {
-  return __detail::__variant::__compare(true, __lhs, __rhs,
-   [](auto&& __l, auto&& __r) {
- return __l == __r;
-   });
+  namespace __variant = __detail::__variant;
+  return __variant::__compare(true, __lhs, __rhs,
+ [](auto&& __l, auto&& __r) -> bool {
+   return __l == __r;
+ });
 }
 
   template
@@ -1286,10 +1287,11 @@ namespace __detail::__variant
 operator!= [[nodiscard]] (const variant<_Types...>& __lhs,
  const variant<_Types...>& __rhs)
 {
-  return __detail::__variant::__compare(true, __lhs, __rhs,
-   [](auto&& __l, auto&& __r) {
- return __l != __r;
-   });
+  namespace __variant = __detail::__variant;
+  return __variant::__compare(true, __lhs, __rhs,
+ [](auto&& __l, auto&& __r) -> bool {
+   return __l != __r;
+ });
 }
 
   template
@@ -1301,10 +1303,11 @@ namespace __detail::__variant
 operator< [[nodiscard]] (const variant<_Types...>& __lhs,
 const variant<_Types...>& __rhs)
 {
-  return __detail::__variant::__compare(true, __lhs, __rhs,
-   [](auto&& __l, auto&& __r) {
- return __l < __r;
-   });
+  namespace __variant = __detail::__variant;
+  return __variant::__compare(true, __lhs, __rhs,
+ [](auto&& __l, auto&& __r) -> bool {
+   return __l < __r;
+ });
 }
 
   template
@@ -1316,10 +1319,11 @@ namespace __detail::__variant
 operator<= [[nodiscard]] (const variant<_Types...>& __lhs,
  const variant<_Types...>& __rhs)
 {
-  return __detail::__variant::__compare(true, __lhs, __rhs,
-   [](auto&& __l, auto&& __r) {
- return __l <= __r;
-   });
+  namespace __variant = __detail::__variant;
+  return __variant::__compare(true, __lhs, __rhs,
+ [](auto&& __l, auto&& __r) -> bool {
+   return __l <= __r;
+ });
 }
 
   template
@@ -1331,10 +1335,11 @@ namespace __detail::__variant
 operator> [[nodiscard]] (const variant<_Types...>& __lhs,
 const variant<_Types...>& __rhs)
 {
-  return __detail::__variant::__compare(true, __lhs, __rhs,
-   [](auto&& __l, auto&& __r) {
- return __l > __r;
-   });
+  namespace __variant = __detail::__variant;
+  return __variant::__compare(true, __lhs, __rhs,
+ [](auto&& __l, auto&& __r) -> bool {
+   

[gcc r13-8789] libstdc++: testsuite: Enhance codecvt_unicode with tests for length()

2024-05-21 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:9433e308e0ca48822aa5e3a9875aac1f86cbac72

commit r13-8789-g9433e308e0ca48822aa5e3a9875aac1f86cbac72
Author: Dimitrij Mijoski 
Date:   Wed Oct 18 12:52:20 2023 +0200

libstdc++: testsuite: Enhance codecvt_unicode with tests for length()

We can test codecvt::length() with the same data that we test
codecvt::in(). For each call of in() we add another call to length().
Some additional small cosmentic changes are applied.

libstdc++-v3/ChangeLog:

* testsuite/22_locale/codecvt/codecvt_unicode.h: Test length()

(cherry picked from commit 59a7d38997ec4d8a606c97b00e1a8b697edd1316)

Diff:
---
 .../testsuite/22_locale/codecvt/codecvt_unicode.h  | 123 ++---
 1 file changed, 110 insertions(+), 13 deletions(-)

diff --git a/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_unicode.h 
b/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_unicode.h
index d3ae42fac13..42270c50f14 100644
--- a/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_unicode.h
+++ b/libstdc++-v3/testsuite/22_locale/codecvt/codecvt_unicode.h
@@ -17,7 +17,6 @@
 
 #include 
 #include 
-#include 
 #include 
 
 struct test_offsets_ok
@@ -79,6 +78,11 @@ utf8_to_utf32_in_ok (const std::codecvt )
   VERIFY (char_traits::compare (out, exp, t.out_size) == 0);
   if (t.out_size < array_size (out))
VERIFY (out[t.out_size] == 0);
+
+  state = {};
+  auto len = cvt.length (state, in, in + t.in_size, t.out_size);
+  VERIFY (len >= 0);
+  VERIFY (static_cast (len) == t.in_size);
 }
 
   for (auto t : offsets)
@@ -99,6 +103,11 @@ utf8_to_utf32_in_ok (const std::codecvt )
   VERIFY (char_traits::compare (out, exp, t.out_size) == 0);
   if (t.out_size < array_size (out))
VERIFY (out[t.out_size] == 0);
+
+  state = {};
+  auto len = cvt.length (state, in, in + t.in_size, array_size (out));
+  VERIFY (len >= 0);
+  VERIFY (static_cast (len) == t.in_size);
 }
 }
 
@@ -163,6 +172,11 @@ utf8_to_utf32_in_partial (const std::codecvt )
  == 0);
   if (t.expected_out_next < array_size (out))
VERIFY (out[t.expected_out_next] == 0);
+
+  state = {};
+  auto len = cvt.length (state, in, in + t.in_size, t.out_size);
+  VERIFY (len >= 0);
+  VERIFY (static_cast (len) == t.expected_in_next);
 }
 }
 
@@ -303,6 +317,11 @@ utf8_to_utf32_in_error (const std::codecvt )
   if (t.expected_out_next < array_size (out))
VERIFY (out[t.expected_out_next] == 0);
 
+  state = {};
+  auto len = cvt.length (state, in, in + t.in_size, t.out_size);
+  VERIFY (len >= 0);
+  VERIFY (static_cast (len) == t.expected_in_next);
+
   in[t.replace_pos] = old_char;
 }
 }
@@ -334,7 +353,7 @@ utf32_to_utf8_out_ok (const std::codecvt )
   VERIFY (char_traits::length (in) == 4);
   VERIFY (char_traits::length (exp) == 10);
 
-  const test_offsets_ok offsets[] = {{0, 0}, {1, 1}, {2, 3}, {3, 6}, {4, 10}};
+  test_offsets_ok offsets[] = {{0, 0}, {1, 1}, {2, 3}, {3, 6}, {4, 10}};
   for (auto t : offsets)
 {
   ExternT out[array_size (exp) - 1] = {};
@@ -374,7 +393,7 @@ utf32_to_utf8_out_partial (const std::codecvt )
   VERIFY (char_traits::length (in) == 4);
   VERIFY (char_traits::length (exp) == 10);
 
-  const test_offsets_partial offsets[] = {
+  test_offsets_partial offsets[] = {
 {1, 0, 0, 0}, // no space for first CP
 
 {2, 1, 1, 1}, // no space for second CP
@@ -528,6 +547,11 @@ utf8_to_utf16_in_ok (const std::codecvt )
   VERIFY (char_traits::compare (out, exp, t.out_size) == 0);
   if (t.out_size < array_size (out))
VERIFY (out[t.out_size] == 0);
+
+  state = {};
+  auto len = cvt.length (state, in, in + t.in_size, t.out_size);
+  VERIFY (len >= 0);
+  VERIFY (static_cast (len) == t.in_size);
 }
 
   for (auto t : offsets)
@@ -548,6 +572,11 @@ utf8_to_utf16_in_ok (const std::codecvt )
   VERIFY (char_traits::compare (out, exp, t.out_size) == 0);
   if (t.out_size < array_size (out))
VERIFY (out[t.out_size] == 0);
+
+  state = {};
+  auto len = cvt.length (state, in, in + t.in_size, array_size (out));
+  VERIFY (len >= 0);
+  VERIFY (static_cast (len) == t.in_size);
 }
 }
 
@@ -617,6 +646,11 @@ utf8_to_utf16_in_partial (const std::codecvt )
  == 0);
   if (t.expected_out_next < array_size (out))
VERIFY (out[t.expected_out_next] == 0);
+
+  state = {};
+  auto len = cvt.length (state, in, in + t.in_size, t.out_size);
+  VERIFY (len >= 0);
+  VERIFY (static_cast (len) == t.expected_in_next);
 }
 }
 
@@ -757,6 +791,11 @@ utf8_to_utf16_in_error (const std::codecvt )
   if (t.expected_out_next < array_size (out))
VERIFY (out[t.expected_out_next] == 0);
 
+  state = {};
+  auto len = cvt.length (state, in, in + t.in_size, t.out_size);
+  VERIFY (len >= 0);
+  VERIFY (static_cast (len) == t.expected_in_next);
+
   

[gcc r13-8788] libstdc++: Fix handling of surrogate CP in codecvt [PR108976]

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

commit r13-8788-gbd5e672303f5f777e8927a746d3ee42db21d871b
Author: Dimitrij Mijoski 
Date:   Thu Sep 28 21:38:11 2023 +0200

libstdc++: Fix handling of surrogate CP in codecvt [PR108976]

This patch fixes the handling of surrogate code points in all standard
facets for transcoding Unicode that are based on std::codecvt. Surrogate
code points should always be treated as error. On the other hand
surrogate code units can only appear in UTF-16 and only when they come
in a proper pair.

Additionally, it fixes a bug in std::codecvt_utf16::in() when odd number
of bytes were given in the range [from, from_end), error was returned
always. The last byte in such range does not form a full UTF-16 code
unit and we can not make any decisions for error, instead partial should
be returned.

The testsuite for testing these facets was updated in the following
order:

1. All functions that test codecvts that work with UTF-8 were refactored
   and made more generic so they accept codecvt that works with the char
   type char8_t.
2. The same functions were updated with new test cases for transcoding
   errors and now additionally test for surrogates, overlong UTF-8
   sequences, code points out of the Unicode range, and more tests for
   missing leading and trailing code units.
3. New tests were added to test codecvt_utf16 in both of its variants,
   UTF-16 <-> UTF-32/UCS-4 and UTF-16 <-> UCS-2.

libstdc++-v3/ChangeLog:

PR libstdc++/108976
* src/c++11/codecvt.cc (read_utf8_code_point): Fix handing of
surrogates in UTF-8.
(ucs4_out): Fix handling of surrogates in UCS-4 -> UTF-8.
(ucs4_in): Fix handling of range with odd number of bytes.
(ucs4_out): Fix handling of surrogates in UCS-4 -> UTF-16.
(ucs2_out): Fix handling of surrogates in UCS-2 -> UTF-16.
(ucs2_in): Fix handling of range with odd number of bytes.
(__codecvt_utf16_base::do_in): Likewise.
(__codecvt_utf16_base::do_in): Likewise.
(__codecvt_utf16_base::do_in): Likewise.
* testsuite/22_locale/codecvt/codecvt_unicode.cc: Renames, add
tests for codecvt_utf16 and codecvt_utf16.
* testsuite/22_locale/codecvt/codecvt_unicode.h: Refactor UTF-8
testing functions for char8_t, add more test cases for errors,
add testing functions for codecvt_utf16.
* testsuite/22_locale/codecvt/codecvt_unicode_wchar_t.cc:
Renames, add tests for codecvt_utf16.
* testsuite/22_locale/codecvt/codecvt_utf16/79980.cc (test06):
Fix test.
* testsuite/22_locale/codecvt/codecvt_unicode_char8_t.cc: New
test.

(cherry picked from commit a8b9c32da787ea0bfbfc9118ac816fa7be4b1bc8)

Diff:
---
 libstdc++-v3/src/c++11/codecvt.cc  |   18 +-
 .../testsuite/22_locale/codecvt/codecvt_unicode.cc |   38 +-
 .../testsuite/22_locale/codecvt/codecvt_unicode.h  | 1799 +++-
 .../22_locale/codecvt/codecvt_unicode_char8_t.cc   |   53 +
 .../22_locale/codecvt/codecvt_unicode_wchar_t.cc   |   32 +-
 .../22_locale/codecvt/codecvt_utf16/79980.cc   |2 +-
 6 files changed, 1493 insertions(+), 449 deletions(-)

diff --git a/libstdc++-v3/src/c++11/codecvt.cc 
b/libstdc++-v3/src/c++11/codecvt.cc
index 02f05752de8..2cc812cfc34 100644
--- a/libstdc++-v3/src/c++11/codecvt.cc
+++ b/libstdc++-v3/src/c++11/codecvt.cc
@@ -284,6 +284,8 @@ namespace
return invalid_mb_sequence;
   if (c1 == 0xE0 && c2 < 0xA0) [[unlikely]] // overlong
return invalid_mb_sequence;
+  if (c1 == 0xED && c2 >= 0xA0) [[unlikely]] // surrogate
+   return invalid_mb_sequence;
   if (avail < 3) [[unlikely]]
return incomplete_mb_character;
   char32_t c3 = (unsigned char) from[2];
@@ -484,6 +486,8 @@ namespace
 while (from.size())
   {
const char32_t c = from[0];
+   if (0xD800 <= c && c <= 0xDFFF) [[unlikely]]
+ return codecvt_base::error;
if (c > maxcode) [[unlikely]]
  return codecvt_base::error;
if (!write_utf8_code_point(to, c)) [[unlikely]]
@@ -508,7 +512,7 @@ namespace
  return codecvt_base::error;
to = codepoint;
   }
-return from.size() ? codecvt_base::partial : codecvt_base::ok;
+return from.nbytes() ? codecvt_base::partial : codecvt_base::ok;
   }
 
   // ucs4 -> utf16
@@ -521,6 +525,8 @@ namespace
 while (from.size())
   {
const char32_t c = from[0];
+   if (0xD800 <= c && c <= 0xDFFF) [[unlikely]]
+ return codecvt_base::error;
if (c > maxcode) [[unlikely]]
  return codecvt_base::error;
if (!write_utf16_code_point(to, c, mode)) [[unlikely]]
@@ -653,7 +659,7 @@ namespace
 while (from.size() && 

[gcc r13-8787] c++: Fix std dialect hint for std::to_address [PR107800]

2024-05-21 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:0a9df2c711f40e067cd57707d8e623136ae4efbe

commit r13-8787-g0a9df2c711f40e067cd57707d8e623136ae4efbe
Author: Jonathan Wakely 
Date:   Tue May 21 13:16:33 2024 +0100

c++: Fix std dialect hint for std::to_address [PR107800]

The correct dialect for std::to_address is cxx20 not cxx11.

gcc/cp/ChangeLog:

PR libstdc++/107800
* cxxapi-data.csv : Change dialect to cxx20.
* std-name-hint.gperf: Regenerate.
* std-name-hint.h: Regenerate.

(cherry picked from commit 826a7d3d19d3ebf04e21d6f1c89eb341a36fb5d1)

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

diff --git a/gcc/cp/cxxapi-data.csv b/gcc/cp/cxxapi-data.csv
index eb6dbcd6057..aecad73a7e8 100644
--- a/gcc/cp/cxxapi-data.csv
+++ b/gcc/cp/cxxapi-data.csv
@@ -460,7 +460,7 @@
 # unimplemented ,default_accessor,1,no
 # unimplemented ,mdspan,1,cxx23
 ,pointer_traits,1,cxx11
-,to_address,1,cxx11
+,to_address,1,cxx20
 ,align,1,cxx11
 ,assume_aligned,1,cxx20
 ,allocator_arg_t,1,cxx11
diff --git a/gcc/cp/std-name-hint.gperf b/gcc/cp/std-name-hint.gperf
index 758e74f77d6..a46c7f3e68f 100644
--- a/gcc/cp/std-name-hint.gperf
+++ b/gcc/cp/std-name-hint.gperf
@@ -220,7 +220,7 @@ pointer_traits, "", cxx11
 reinterpret_pointer_cast, "", cxx17
 shared_ptr, "", cxx11
 static_pointer_cast, "", cxx11
-to_address, "", cxx11
+to_address, "", cxx20
 uninitialized_construct_using_allocator, "", cxx20
 unique_ptr, "", cxx11
 uses_allocator, "", cxx11
diff --git a/gcc/cp/std-name-hint.h b/gcc/cp/std-name-hint.h
index 5848fca6f0e..8503d195145 100644
--- a/gcc/cp/std-name-hint.h
+++ b/gcc/cp/std-name-hint.h
@@ -291,7 +291,7 @@ std_name_hint_lookup::find (const char *str, size_t len)
 #line 472 "std-name-hint.gperf"
   {"variant_npos", "", cxx17},
 #line 223 "std-name-hint.gperf"
-  {"to_address", "", cxx11},
+  {"to_address", "", cxx20},
 #line 460 "std-name-hint.gperf"
   {"pair", "", cxx98},
 #line 269 "std-name-hint.gperf"


[gcc r14-10227] c++: Fix std dialect hint for std::to_address [PR107800]

2024-05-21 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:5b96d547ce71b8f03ddbc2318c64618110839e20

commit r14-10227-g5b96d547ce71b8f03ddbc2318c64618110839e20
Author: Jonathan Wakely 
Date:   Tue May 21 13:16:33 2024 +0100

c++: Fix std dialect hint for std::to_address [PR107800]

The correct dialect for std::to_address is cxx20 not cxx11.

gcc/cp/ChangeLog:

PR libstdc++/107800
* cxxapi-data.csv : Change dialect to cxx20.
* std-name-hint.gperf: Regenerate.
* std-name-hint.h: Regenerate.

(cherry picked from commit 826a7d3d19d3ebf04e21d6f1c89eb341a36fb5d1)

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

diff --git a/gcc/cp/cxxapi-data.csv b/gcc/cp/cxxapi-data.csv
index 75ee1b3ac92..1cbf774acd7 100644
--- a/gcc/cp/cxxapi-data.csv
+++ b/gcc/cp/cxxapi-data.csv
@@ -460,7 +460,7 @@
 # unimplemented ,default_accessor,1,no
 # unimplemented ,mdspan,1,cxx23
 ,pointer_traits,1,cxx11
-,to_address,1,cxx11
+,to_address,1,cxx20
 ,align,1,cxx11
 ,assume_aligned,1,cxx20
 ,allocator_arg_t,1,cxx11
diff --git a/gcc/cp/std-name-hint.gperf b/gcc/cp/std-name-hint.gperf
index b26bc6949ba..4fb23da40a6 100644
--- a/gcc/cp/std-name-hint.gperf
+++ b/gcc/cp/std-name-hint.gperf
@@ -220,7 +220,7 @@ pointer_traits, "", cxx11
 reinterpret_pointer_cast, "", cxx17
 shared_ptr, "", cxx11
 static_pointer_cast, "", cxx11
-to_address, "", cxx11
+to_address, "", cxx20
 uninitialized_construct_using_allocator, "", cxx20
 unique_ptr, "", cxx11
 uses_allocator, "", cxx11
diff --git a/gcc/cp/std-name-hint.h b/gcc/cp/std-name-hint.h
index e37d769c1ce..231689355d1 100644
--- a/gcc/cp/std-name-hint.h
+++ b/gcc/cp/std-name-hint.h
@@ -291,7 +291,7 @@ std_name_hint_lookup::find (const char *str, size_t len)
 #line 472 "std-name-hint.gperf"
   {"variant_npos", "", cxx17},
 #line 223 "std-name-hint.gperf"
-  {"to_address", "", cxx11},
+  {"to_address", "", cxx20},
 #line 460 "std-name-hint.gperf"
   {"pair", "", cxx98},
 #line 269 "std-name-hint.gperf"


[committed] c++: Fix std dialect hint for std::to_address [PR107800]

2024-05-21 Thread Jonathan Wakely
Tested x86_64-linux. Committed as obvious.

I'll backport it too.

-- >8 --

The correct dialect for std::to_address is cxx20 not cxx11.

gcc/cp/ChangeLog:

PR libstdc++/107800
* cxxapi-data.csv : Change dialect to cxx20.
* std-name-hint.gperf: Regenerate.
* std-name-hint.h: Regenerate.
---
 gcc/cp/cxxapi-data.csv | 2 +-
 gcc/cp/std-name-hint.gperf | 2 +-
 gcc/cp/std-name-hint.h | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/gcc/cp/cxxapi-data.csv b/gcc/cp/cxxapi-data.csv
index 75ee1b3ac92..1cbf774acd7 100644
--- a/gcc/cp/cxxapi-data.csv
+++ b/gcc/cp/cxxapi-data.csv
@@ -460,7 +460,7 @@
 # unimplemented ,default_accessor,1,no
 # unimplemented ,mdspan,1,cxx23
 ,pointer_traits,1,cxx11
-,to_address,1,cxx11
+,to_address,1,cxx20
 ,align,1,cxx11
 ,assume_aligned,1,cxx20
 ,allocator_arg_t,1,cxx11
diff --git a/gcc/cp/std-name-hint.gperf b/gcc/cp/std-name-hint.gperf
index b26bc6949ba..4fb23da40a6 100644
--- a/gcc/cp/std-name-hint.gperf
+++ b/gcc/cp/std-name-hint.gperf
@@ -220,7 +220,7 @@ pointer_traits, "", cxx11
 reinterpret_pointer_cast, "", cxx17
 shared_ptr, "", cxx11
 static_pointer_cast, "", cxx11
-to_address, "", cxx11
+to_address, "", cxx20
 uninitialized_construct_using_allocator, "", cxx20
 unique_ptr, "", cxx11
 uses_allocator, "", cxx11
diff --git a/gcc/cp/std-name-hint.h b/gcc/cp/std-name-hint.h
index e37d769c1ce..231689355d1 100644
--- a/gcc/cp/std-name-hint.h
+++ b/gcc/cp/std-name-hint.h
@@ -291,7 +291,7 @@ std_name_hint_lookup::find (const char *str, size_t len)
 #line 472 "std-name-hint.gperf"
   {"variant_npos", "", cxx17},
 #line 223 "std-name-hint.gperf"
-  {"to_address", "", cxx11},
+  {"to_address", "", cxx20},
 #line 460 "std-name-hint.gperf"
   {"pair", "", cxx98},
 #line 269 "std-name-hint.gperf"
-- 
2.45.1



[gcc r15-760] c++: Fix std dialect hint for std::to_address [PR107800]

2024-05-21 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:826a7d3d19d3ebf04e21d6f1c89eb341a36fb5d1

commit r15-760-g826a7d3d19d3ebf04e21d6f1c89eb341a36fb5d1
Author: Jonathan Wakely 
Date:   Tue May 21 13:16:33 2024 +0100

c++: Fix std dialect hint for std::to_address [PR107800]

The correct dialect for std::to_address is cxx20 not cxx11.

gcc/cp/ChangeLog:

PR libstdc++/107800
* cxxapi-data.csv : Change dialect to cxx20.
* std-name-hint.gperf: Regenerate.
* std-name-hint.h: Regenerate.

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

diff --git a/gcc/cp/cxxapi-data.csv b/gcc/cp/cxxapi-data.csv
index 75ee1b3ac92..1cbf774acd7 100644
--- a/gcc/cp/cxxapi-data.csv
+++ b/gcc/cp/cxxapi-data.csv
@@ -460,7 +460,7 @@
 # unimplemented ,default_accessor,1,no
 # unimplemented ,mdspan,1,cxx23
 ,pointer_traits,1,cxx11
-,to_address,1,cxx11
+,to_address,1,cxx20
 ,align,1,cxx11
 ,assume_aligned,1,cxx20
 ,allocator_arg_t,1,cxx11
diff --git a/gcc/cp/std-name-hint.gperf b/gcc/cp/std-name-hint.gperf
index b26bc6949ba..4fb23da40a6 100644
--- a/gcc/cp/std-name-hint.gperf
+++ b/gcc/cp/std-name-hint.gperf
@@ -220,7 +220,7 @@ pointer_traits, "", cxx11
 reinterpret_pointer_cast, "", cxx17
 shared_ptr, "", cxx11
 static_pointer_cast, "", cxx11
-to_address, "", cxx11
+to_address, "", cxx20
 uninitialized_construct_using_allocator, "", cxx20
 unique_ptr, "", cxx11
 uses_allocator, "", cxx11
diff --git a/gcc/cp/std-name-hint.h b/gcc/cp/std-name-hint.h
index e37d769c1ce..231689355d1 100644
--- a/gcc/cp/std-name-hint.h
+++ b/gcc/cp/std-name-hint.h
@@ -291,7 +291,7 @@ std_name_hint_lookup::find (const char *str, size_t len)
 #line 472 "std-name-hint.gperf"
   {"variant_npos", "", cxx17},
 #line 223 "std-name-hint.gperf"
-  {"to_address", "", cxx11},
+  {"to_address", "", cxx20},
 #line 460 "std-name-hint.gperf"
   {"pair", "", cxx98},
 #line 269 "std-name-hint.gperf"


Re: GCC Installation breaks older header files

2024-05-21 Thread Jonathan Wakely via Gcc-bugs

This mailing list is for automated mail from our bugzilla database,
not for reporting bugs. It looks like you should be using the gcc-help
mailing list anyway, not reporting a bug. I've CC'd that list. Please
remove the gcc-bugs mailing list from the CC list when replying.

On 20/05/24 20:48 +, novaTopFlex wrote:

For system information results as necessary:

Result from uname -a​:

Linux ubuntu-macbookpro 6.5.0-26-generic #26~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC 
Tue Mar 12 10:22:43 UTC 2 x86_64 x86_64 x86_64 GNU/Linux​​


The system information is not very relevant, but you haven't even said
what version of GCC you're using.



Also, there is no specific software or hardware being affected; this is a 
large-scale issue for developers needing to switch versions of the 
cross-compiler.

Sent with [Proton Mail](https://proton.me/) secure email.

On Monday, May 20th, 2024 at 4:45 PM, novaTopFlex  
wrote:


I am sorry to report that existing header files may have been broken by the 
installation of a newer version of GCC. I have continuously attempted to 
compile newer versions of GCC from source but my system continuously fails to 
compile the code. I am not sure if there is any recovery path to restore 
success for applications that had depended on these headers. Sorry for the 
interruption.


Nobody can help you with such a vague description of the problem.

What do you mean "broken"? Which header files? What happens?

What command are you running, and what errors do you get?

Where did you install the new GCC? Did you overwrite an old version,
or install to a different location? How did you configure and build
GCC?

Maybe you just need to run the mkheaders script as documented at
https://gcc.gnu.org/onlinedocs/gcc-14.1.0/gcc/Fixed-Headers.html




Re: [PATCH] Fix overwriting files with fs::copy_file on windows

2024-05-17 Thread Jonathan Wakely
On Sun, 24 Mar 2024 at 21:34, Björn Schäpers  wrote:
>
> From: Björn Schäpers 
>
> This fixes i.e. https://github.com/msys2/MSYS2-packages/issues/1937
> I don't know if I picked the right way to do it.
>
> When acceptable I think the declaration should be moved into
> ops-common.h, since then we could use stat_type and also use that in the
> commonly used function.
>
> Manually tested on i686-w64-mingw32.
>
> -- >8 --
> libstdc++: Fix overwriting files on windows
>
> The inodes have no meaning on windows, thus all files have an inode of
> 0. Use a differenz approach to identify equivalent files. As a result
> std::filesystem::copy_file did not honor
> copy_options::overwrite_existing. Factored the method out of
> std::filesystem::equivalent.
>
> libstdc++-v3/Changelog:
>
> * include/bits/fs_ops.h: Add declaration of
>   __detail::equivalent_win32.
> * src/c++17/fs_ops.cc (__detail::equivalent_win32): Implement it
> (fs::equivalent): Use __detail::equivalent_win32, factored the
> old test out.
> * src/filesystem/ops-common.h (_GLIBCXX_FILESYSTEM_IS_WINDOWS):
>   Use the function.
>
> Signed-off-by: Björn Schäpers 
> ---
>  libstdc++-v3/include/bits/fs_ops.h   |  8 +++
>  libstdc++-v3/src/c++17/fs_ops.cc | 79 +---
>  libstdc++-v3/src/filesystem/ops-common.h | 10 ++-
>  3 files changed, 60 insertions(+), 37 deletions(-)
>
> diff --git a/libstdc++-v3/include/bits/fs_ops.h 
> b/libstdc++-v3/include/bits/fs_ops.h
> index 90650c47b46..d10b78a4bdd 100644
> --- a/libstdc++-v3/include/bits/fs_ops.h
> +++ b/libstdc++-v3/include/bits/fs_ops.h
> @@ -40,6 +40,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>
>  namespace filesystem
>  {
> +#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
> +namespace __detail
> +{
> +  bool
> +  equivalent_win32(const wchar_t* p1, const wchar_t* p2, error_code& ec);

I don't think we want this declared in the public header, it should be
internal to the library.

Can it just be declared in ops-common.h instead?


> +} // namespace __detail
> +#endif //_GLIBCXX_FILESYSTEM_IS_WINDOWS
> +
>/** @addtogroup filesystem
> *  @{
> */
> diff --git a/libstdc++-v3/src/c++17/fs_ops.cc 
> b/libstdc++-v3/src/c++17/fs_ops.cc
> index 61df19753ef..3cc87d45237 100644
> --- a/libstdc++-v3/src/c++17/fs_ops.cc
> +++ b/libstdc++-v3/src/c++17/fs_ops.cc
> @@ -67,6 +67,49 @@
>  namespace fs = std::filesystem;
>  namespace posix = std::filesystem::__gnu_posix;
>
> +#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
> +bool
> +fs::__detail::equivalent_win32(const wchar_t* p1, const wchar_t* p2,
> +  error_code& ec)
> +{
> +  struct auto_handle {
> +explicit auto_handle(const path& p_)
> +: handle(CreateFileW(p_.c_str(), 0,
> +   FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
> +   0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0))
> +{ }
> +
> +~auto_handle()
> +{ if (*this) CloseHandle(handle); }
> +
> +explicit operator bool() const
> +{ return handle != INVALID_HANDLE_VALUE; }
> +
> +bool get_info()
> +{ return GetFileInformationByHandle(handle, ); }
> +
> +HANDLE handle;
> +BY_HANDLE_FILE_INFORMATION info;
> +  };
> +  auto_handle h1(p1);

This creates a new filesystem::path, just to call c_str() on it
immediately. The auto_handle ctor should be changed to just take const
wchar_t* so we don't need to allocate and parse new path objects.

> +  auto_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
> +
>  fs::path
>  fs::absolute(const path& p)
>  {
> @@ -858,41 +901,7 @@ fs::equivalent(const path& p1, const path& p2, 
> error_code& ec) noexcept
>if (st1.st_mode != st2.st_mode || st1.st_dev != st2.st_dev)
> return false;
>
> -  struct auto_handle {
> -   explicit auto_handle(const path& p_)
> -   : handle(CreateFileW(p_.c_str(), 0,
> - FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
> - 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0))
> -   { }
> -
> -   ~auto_handle()
> -   { if (*this) CloseHandle(handle); }
> -
> -   explicit operator bool() const
> -   { return handle != INVALID_HANDLE_VALUE; }
> -
> -   bool get_info()
> -   { return GetFileInformationByHandle(handle, ); }
> -
> -   HANDLE handle;
> -   BY_HANDLE_FILE_INFORMATION info;
> -  };
> -  auto_handle h1(p1);
> -  auto_handle h2(p2);
> -  if (!h1 || !h2)
> -   {
> - if (!h1 && !h2)
> -   ec = __last_system_error();
> -   

[gcc r15-631] libstdc++: detect DLLs on windows with

2024-05-17 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:d4635b504c73b653b815d2c2543c86c91b00e373

commit r15-631-gd4635b504c73b653b815d2c2543c86c91b00e373
Author: Björn Schäpers 
Date:   Fri May 17 11:45:28 2024 +0100

libstdc++: detect DLLs on windows with 

libstdc++-v3/ChangeLog:

* acinclude.m4 (GLIBCXX_ENABLE_BACKTACE): Add check for
tlhelp32.h, matching libbacktrace.
* config.h.in: Regenerate.
* configure: Regenerate.

Signed-off-by: Björn Schäpers 

Diff:
---
 libstdc++-v3/acinclude.m4 |  5 +
 libstdc++-v3/config.h.in  |  3 +++
 libstdc++-v3/configure| 16 
 3 files changed, 24 insertions(+)

diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index 51a08bcc8b1d..e04aae25360d 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -5481,6 +5481,11 @@ AC_DEFUN([GLIBCXX_ENABLE_BACKTRACE], [
 BACKTRACE_CPPFLAGS="$BACKTRACE_CPPFLAGS -DHAVE_DL_ITERATE_PHDR=1"
   fi
   AC_CHECK_HEADERS(windows.h)
+  AC_CHECK_HEADERS(tlhelp32.h, [], [],
+  [#ifdef HAVE_WINDOWS_H
+  #  include 
+  #endif
+  ])
 
   # Check for the fcntl function.
   if test -n "${with_target_subdir}"; then
diff --git a/libstdc++-v3/config.h.in b/libstdc++-v3/config.h.in
index 906e0143099e..486ba4507499 100644
--- a/libstdc++-v3/config.h.in
+++ b/libstdc++-v3/config.h.in
@@ -490,6 +490,9 @@
 /* Define to 1 if you have the `timespec_get' function. */
 #undef HAVE_TIMESPEC_GET
 
+/* Define to 1 if you have the  header file. */
+#undef HAVE_TLHELP32_H
+
 /* Define to 1 if the target supports thread-local storage. */
 #undef HAVE_TLS
 
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index 21abaeb07788..5179cc507f12 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -53865,6 +53865,22 @@ _ACEOF
 
 fi
 
+done
+
+  for ac_header in tlhelp32.h
+do :
+  ac_fn_c_check_header_compile "$LINENO" "tlhelp32.h" 
"ac_cv_header_tlhelp32_h" "#ifdef HAVE_WINDOWS_H
+  #  include 
+  #endif
+
+"
+if test "x$ac_cv_header_tlhelp32_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_TLHELP32_H 1
+_ACEOF
+
+fi
+
 done


[PATCH] libstdc++: Implement std::formatter without [PR115099]

2024-05-17 Thread Jonathan Wakely
Does anybody see any issue with the drive-by fixes to constraint
std::formatter to only work for pointers and integers (since
we don't know how to format pthread_t if it's an arbitrary struct, for
example), and to cast pointers to const void* for output (because if
pthread_t is char* then writing it to a stream would be bad! and we
don't want to allow users to overload operator<< for pointers to opaque
structs, for example). I don't think this will change anything in
practice for common targets, where pthread_t is either an integer or
void*.

Tested x86_64-linux.

-- >8 --

The std::thread::id formatter uses std::basic_ostringstream without
including , which went unnoticed because the test for it uses
a stringstream to check the output is correct.

The fix implemented here is to stop using basic_ostringstream for
formatting thread::id and just use std::format instead.

As a drive-by fix, the formatter specialization is constrained to
require that the thread::id::native_handle_type can be formatted, to
avoid making the formatter ill-formed if the pthread_t type is not a
pointer or integer. Since non-void pointers can't be formatted, ensure
that we convert pointers to const void* for formatting. Make a similar
change to the existing operator<< overload so that in the unlikely case
that pthread_t is a typedef for char* we don't treat it as a
null-terminated string when inserting into a stream.

libstdc++-v3/ChangeLog:

PR libstdc++/115099
* include/bits/std_thread.h: Declare formatter as friend of
thread::id.
* include/std/thread (operator<<): Convert non-void pointers to
void pointers for output.
(formatter): Add constraint that thread::native_handle_type is a
pointer or integer.
(formatter::format): Reimplement without basic_ostringstream.
* testsuite/30_threads/thread/id/output.cc: Check output
compiles before  has been included.
---
 libstdc++-v3/include/bits/std_thread.h| 11 -
 libstdc++-v3/include/std/thread   | 43 ++-
 .../testsuite/30_threads/thread/id/output.cc  | 21 -
 3 files changed, 63 insertions(+), 12 deletions(-)

diff --git a/libstdc++-v3/include/bits/std_thread.h 
b/libstdc++-v3/include/bits/std_thread.h
index 2d7df12650d..5817bfb29dd 100644
--- a/libstdc++-v3/include/bits/std_thread.h
+++ b/libstdc++-v3/include/bits/std_thread.h
@@ -53,6 +53,10 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
+#if __glibcxx_formatters
+  template class formatter;
+#endif
+
   /** @addtogroup threads
*  @{
*/
@@ -117,13 +121,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
friend basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __out, id __id);
+
+#if __glibcxx_formatters
+  friend formatter;
+  friend formatter;
+#endif
 };
 
   private:
 id _M_id;
 
 // _GLIBCXX_RESOLVE_LIB_DEFECTS
-// 2097.  packaged_task constructors should be constrained
+// 2097. packaged_task constructors should be constrained
 // 3039. Unnecessary decay in thread and packaged_task
 template
   using __not_same = __not_, thread>>;
diff --git a/libstdc++-v3/include/std/thread b/libstdc++-v3/include/std/thread
index 09ca3116e7f..e994d683bff 100644
--- a/libstdc++-v3/include/std/thread
+++ b/libstdc++-v3/include/std/thread
@@ -42,10 +42,6 @@
 # include  // std::stop_source, std::stop_token, std::nostopstate
 #endif
 
-#if __cplusplus > 202002L
-# include 
-#endif
-
 #include  // std::thread, get_id, yield
 #include  // std::this_thread::sleep_for, sleep_until
 
@@ -53,6 +49,10 @@
 #define __glibcxx_want_formatters
 #include 
 
+#if __cpp_lib_formatters
+# include 
+#endif
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -104,10 +104,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 inline basic_ostream<_CharT, _Traits>&
 operator<<(basic_ostream<_CharT, _Traits>& __out, thread::id __id)
 {
+  // Convert non-void pointers to const void* for formatted output.
+  using __output_type
+   = __conditional_t::value,
+ const void*,
+ thread::native_handle_type>;
+
   if (__id == thread::id())
return __out << "thread::id of a non-executing thread";
   else
-   return __out << __id._M_thread;
+   return __out << static_cast<__output_type>(__id._M_thread);
 }
   /// @}
 
@@ -287,8 +293,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif // __cpp_lib_jthread
 
 #ifdef __cpp_lib_formatters // C++ >= 23
-
   template
+requires is_pointer_v
+  || is_integral_v
 class formatter
 {
 public:
@@ -331,10 +338,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename basic_format_context<_Out, _CharT>::iterator
format(thread::id __id, basic_format_context<_Out, _CharT>& __fc) const
{
- std::basic_ostringstream<_CharT> 

[gcc r14-10215] libstdc++: Fix typo in _Grapheme_cluster_view::_Iterator [PR115119]

2024-05-17 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:e909d360dfaeafa9f45eda2461a1bedffac99ac2

commit r14-10215-ge909d360dfaeafa9f45eda2461a1bedffac99ac2
Author: Jonathan Wakely 
Date:   Thu May 16 17:15:55 2024 +0100

libstdc++: Fix typo in _Grapheme_cluster_view::_Iterator [PR115119]

libstdc++-v3/ChangeLog:

PR libstdc++/115119
* include/bits/unicode.h (_Iterator::operator++(int)): Fix typo
in increment expression.
* testsuite/ext/unicode/grapheme_view.cc: Check post-increment
on view's iterator.

(cherry picked from commit c9e05b03c18e898be604ab90401476e9c473cc52)

Diff:
---
 libstdc++-v3/include/bits/unicode.h |  6 --
 libstdc++-v3/testsuite/ext/unicode/grapheme_view.cc | 11 +++
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/bits/unicode.h 
b/libstdc++-v3/include/bits/unicode.h
index 46238143fb61..a14a17c5dfcf 100644
--- a/libstdc++-v3/include/bits/unicode.h
+++ b/libstdc++-v3/include/bits/unicode.h
@@ -34,10 +34,12 @@
 #include 
 #include   // bit_width
 #include  // __detail::__from_chars_alnum_to_val_table
+#include 
 #include 
 #include 
 #include 
-#include 
+#include  // iterator_t, sentinel_t, input_range, etc.
+#include  // view_interface
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -802,7 +804,7 @@ inline namespace __v15_1_0
operator++(int)
{
  auto __tmp = *this;
- ++this;
+ ++*this;
  return __tmp;
}
 
diff --git a/libstdc++-v3/testsuite/ext/unicode/grapheme_view.cc 
b/libstdc++-v3/testsuite/ext/unicode/grapheme_view.cc
index ac1e8c50b059..a3bb36e14b8e 100644
--- a/libstdc++-v3/testsuite/ext/unicode/grapheme_view.cc
+++ b/libstdc++-v3/testsuite/ext/unicode/grapheme_view.cc
@@ -83,10 +83,21 @@ test_breaks()
   VERIFY( iter == gv.end() );
 }
 
+constexpr void
+test_pr115119()
+{
+  // PR 115119 Typo in _Grapheme_cluster_view::_Iterator::operator++(int)
+  uc::_Grapheme_cluster_view gv(" "sv);
+  auto it = std::ranges::begin(gv);
+  it++;
+  VERIFY( it == std::ranges::end(gv) );
+}
+
 int main()
 {
   auto run_tests = []{
 test_breaks();
+test_pr115119();
 return true;
   };


[committed] libstdc++: Fix typo in _Grapheme_cluster_view::_Iterator [PR115119]

2024-05-17 Thread Jonathan Wakely
Tested x86_64-linux. Pushed to trunk, gcc-14 backport to follow.

-- >8 --

libstdc++-v3/ChangeLog:

PR libstdc++/115119
* include/bits/unicode.h (_Iterator::operator++(int)): Fix typo
in increment expression.
* testsuite/ext/unicode/grapheme_view.cc: Check post-increment
on view's iterator.
---
 libstdc++-v3/include/bits/unicode.h |  6 --
 libstdc++-v3/testsuite/ext/unicode/grapheme_view.cc | 11 +++
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/bits/unicode.h 
b/libstdc++-v3/include/bits/unicode.h
index 46238143fb6..a14a17c5dfc 100644
--- a/libstdc++-v3/include/bits/unicode.h
+++ b/libstdc++-v3/include/bits/unicode.h
@@ -34,10 +34,12 @@
 #include 
 #include   // bit_width
 #include  // __detail::__from_chars_alnum_to_val_table
+#include 
 #include 
 #include 
 #include 
-#include 
+#include  // iterator_t, sentinel_t, input_range, etc.
+#include  // view_interface
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -802,7 +804,7 @@ inline namespace __v15_1_0
operator++(int)
{
  auto __tmp = *this;
- ++this;
+ ++*this;
  return __tmp;
}
 
diff --git a/libstdc++-v3/testsuite/ext/unicode/grapheme_view.cc 
b/libstdc++-v3/testsuite/ext/unicode/grapheme_view.cc
index ac1e8c50b05..a3bb36e14b8 100644
--- a/libstdc++-v3/testsuite/ext/unicode/grapheme_view.cc
+++ b/libstdc++-v3/testsuite/ext/unicode/grapheme_view.cc
@@ -83,10 +83,21 @@ test_breaks()
   VERIFY( iter == gv.end() );
 }
 
+constexpr void
+test_pr115119()
+{
+  // PR 115119 Typo in _Grapheme_cluster_view::_Iterator::operator++(int)
+  uc::_Grapheme_cluster_view gv(" "sv);
+  auto it = std::ranges::begin(gv);
+  it++;
+  VERIFY( it == std::ranges::end(gv) );
+}
+
 int main()
 {
   auto run_tests = []{
 test_breaks();
+test_pr115119();
 return true;
   };
 
-- 
2.45.0



[gcc r15-629] libstdc++: Fix typo in _Grapheme_cluster_view::_Iterator [PR115119]

2024-05-17 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:c9e05b03c18e898be604ab90401476e9c473cc52

commit r15-629-gc9e05b03c18e898be604ab90401476e9c473cc52
Author: Jonathan Wakely 
Date:   Thu May 16 17:15:55 2024 +0100

libstdc++: Fix typo in _Grapheme_cluster_view::_Iterator [PR115119]

libstdc++-v3/ChangeLog:

PR libstdc++/115119
* include/bits/unicode.h (_Iterator::operator++(int)): Fix typo
in increment expression.
* testsuite/ext/unicode/grapheme_view.cc: Check post-increment
on view's iterator.

Diff:
---
 libstdc++-v3/include/bits/unicode.h |  6 --
 libstdc++-v3/testsuite/ext/unicode/grapheme_view.cc | 11 +++
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/bits/unicode.h 
b/libstdc++-v3/include/bits/unicode.h
index 46238143fb61..a14a17c5dfcf 100644
--- a/libstdc++-v3/include/bits/unicode.h
+++ b/libstdc++-v3/include/bits/unicode.h
@@ -34,10 +34,12 @@
 #include 
 #include   // bit_width
 #include  // __detail::__from_chars_alnum_to_val_table
+#include 
 #include 
 #include 
 #include 
-#include 
+#include  // iterator_t, sentinel_t, input_range, etc.
+#include  // view_interface
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -802,7 +804,7 @@ inline namespace __v15_1_0
operator++(int)
{
  auto __tmp = *this;
- ++this;
+ ++*this;
  return __tmp;
}
 
diff --git a/libstdc++-v3/testsuite/ext/unicode/grapheme_view.cc 
b/libstdc++-v3/testsuite/ext/unicode/grapheme_view.cc
index ac1e8c50b059..a3bb36e14b8e 100644
--- a/libstdc++-v3/testsuite/ext/unicode/grapheme_view.cc
+++ b/libstdc++-v3/testsuite/ext/unicode/grapheme_view.cc
@@ -83,10 +83,21 @@ test_breaks()
   VERIFY( iter == gv.end() );
 }
 
+constexpr void
+test_pr115119()
+{
+  // PR 115119 Typo in _Grapheme_cluster_view::_Iterator::operator++(int)
+  uc::_Grapheme_cluster_view gv(" "sv);
+  auto it = std::ranges::begin(gv);
+  it++;
+  VERIFY( it == std::ranges::end(gv) );
+}
+
 int main()
 {
   auto run_tests = []{
 test_breaks();
+test_pr115119();
 return true;
   };


Re: [PATCH] libstdc++: detect DLLs on windows with

2024-05-17 Thread Jonathan Wakely
On Thu, 16 May 2024 at 19:52, Björn Schäpers  wrote:
>
> From: Björn Schäpers 
>
> libstdc++-v3/Changelog
>
> * acinclude.m4 (GLIBCXX_ENABLE_BACKTACE): Add check for
>   tlhelp32.h, matching libbacktrace.
> * configure: Regenerate.
> * config.h.in: Regenerate.

This looks good, thanks. I'll apply to trunk and probably backport it too.


>
> Signed-off-by: Björn Schäpers 
> ---
>  libstdc++-v3/acinclude.m4 |  4 
>  libstdc++-v3/config.h.in  |  3 +++
>  libstdc++-v3/configure| 15 +++
>  3 files changed, 22 insertions(+)
>
> diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
> index 51a08bcc8b1..506ce98ae43 100644
> --- a/libstdc++-v3/acinclude.m4
> +++ b/libstdc++-v3/acinclude.m4
> @@ -5481,6 +5481,10 @@ AC_DEFUN([GLIBCXX_ENABLE_BACKTRACE], [
>  BACKTRACE_CPPFLAGS="$BACKTRACE_CPPFLAGS -DHAVE_DL_ITERATE_PHDR=1"
>fi
>AC_CHECK_HEADERS(windows.h)
> +  AC_CHECK_HEADERS(tlhelp32.h, [], [],
> +  [#ifdef HAVE_WINDOWS_H
> +  #  include 
> +  #endif])
>
># Check for the fcntl function.
>if test -n "${with_target_subdir}"; then
> diff --git a/libstdc++-v3/config.h.in b/libstdc++-v3/config.h.in
> index 906e0143099..486ba450749 100644
> --- a/libstdc++-v3/config.h.in
> +++ b/libstdc++-v3/config.h.in
> @@ -490,6 +490,9 @@
>  /* Define to 1 if you have the `timespec_get' function. */
>  #undef HAVE_TIMESPEC_GET
>
> +/* Define to 1 if you have the  header file. */
> +#undef HAVE_TLHELP32_H
> +
>  /* Define to 1 if the target supports thread-local storage. */
>  #undef HAVE_TLS
>
> diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
> index 21abaeb0778..a2d59520146 100755
> --- a/libstdc++-v3/configure
> +++ b/libstdc++-v3/configure
> @@ -53865,6 +53865,21 @@ _ACEOF
>
>  fi
>
> +done
> +
> +  for ac_header in tlhelp32.h
> +do :
> +  ac_fn_c_check_header_compile "$LINENO" "tlhelp32.h" 
> "ac_cv_header_tlhelp32_h" "#ifdef HAVE_WINDOWS_H
> +  #  include 
> +  #endif
> +"
> +if test "x$ac_cv_header_tlhelp32_h" = xyes; then :
> +  cat >>confdefs.h <<_ACEOF
> +#define HAVE_TLHELP32_H 1
> +_ACEOF
> +
> +fi
> +
>  done
>
>
> --
> 2.44.0
>



Re: [PATCH 1/2] libstdc++: Fix data race in std::basic_ios::fill() [PR77704]

2024-05-15 Thread Jonathan Wakely
Pushed to trunk.

On Tue, 7 May 2024 at 15:04, Jonathan Wakely  wrote:
>
> Tested x86_64-linux. This seems "obviously correct", and I'd like to
> push it. The current code definitely has a data race, i.e. undefined
> behaviour.
>
> -- >8 --
>
> The lazy caching in std::basic_ios::fill() updates a mutable member
> without synchronization, which can cause a data race if two threads both
> call fill() on the same stream object when _M_fill_init is false.
>
> To avoid this we can just cache the _M_fill member and set _M_fill_init
> early in std::basic_ios::init, instead of doing it lazily. As explained
> by the comment in init, there's a good reason for doing it lazily. When
> char_type is neither char nor wchar_t, the locale might not have a
> std::ctype, so getting the fill character would throw an
> exception. The current lazy init allows using unformatted I/O with such
> a stream, because the fill character is never needed and so it doesn't
> matter if the locale doesn't have a ctype facet. We can
> maintain this property by only setting the fill character in
> std::basic_ios::init if the ctype facet is present at that time. If
> fill() is called later and the fill character wasn't set by init, we can
> get it from the stream's current locale at the point when fill() is
> called (and not try to cache it without synchronization).
>
> This causes a change in behaviour for the following program:
>
>   std::ostringstream out;
>   out.imbue(loc);
>   auto fill = out.fill();
>
> Previously the fill character would have been set when fill() is called,
> and so would have used the new locale. This commit changes it so that
> the fill character is set on construction and isn't affected by the new
> locale being imbued later. This new behaviour seems to be what the
> standard requires, and matches MSVC.
>
> The new 27_io/basic_ios/fill/char/fill.cc test verifies that it's still
> possible to use a std::basic_ios without the ctype facet
> being present at construction.
>
> libstdc++-v3/ChangeLog:
>
> PR libstdc++/77704
> * include/bits/basic_ios.h (basic_ios::fill()): Do not modify
> _M_fill and _M_fill_init in a const member function.
> (basic_ios::fill(char_type)): Use _M_fill directly instead of
> calling fill(). Set _M_fill_init to true.
> * include/bits/basic_ios.tcc (basic_ios::init): Set _M_fill and
> _M_fill_init here instead.
> * testsuite/27_io/basic_ios/fill/char/1.cc: New test.
> * testsuite/27_io/basic_ios/fill/wchar_t/1.cc: New test.
> ---
>  libstdc++-v3/include/bits/basic_ios.h | 10 +--
>  libstdc++-v3/include/bits/basic_ios.tcc   | 15 +++-
>  .../testsuite/27_io/basic_ios/fill/char/1.cc  | 78 +++
>  .../27_io/basic_ios/fill/wchar_t/1.cc | 55 +
>  4 files changed, 148 insertions(+), 10 deletions(-)
>  create mode 100644 libstdc++-v3/testsuite/27_io/basic_ios/fill/char/1.cc
>  create mode 100644 libstdc++-v3/testsuite/27_io/basic_ios/fill/wchar_t/1.cc
>
> diff --git a/libstdc++-v3/include/bits/basic_ios.h 
> b/libstdc++-v3/include/bits/basic_ios.h
> index 258e6042b8f..bc3be4d2e37 100644
> --- a/libstdc++-v3/include/bits/basic_ios.h
> +++ b/libstdc++-v3/include/bits/basic_ios.h
> @@ -373,11 +373,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>char_type
>fill() const
>{
> -   if (!_M_fill_init)
> - {
> -   _M_fill = this->widen(' ');
> -   _M_fill_init = true;
> - }
> +   if (__builtin_expect(!_M_fill_init, false))
> + return this->widen(' ');
> return _M_fill;
>}
>
> @@ -393,8 +390,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>char_type
>fill(char_type __ch)
>{
> -   char_type __old = this->fill();
> +   char_type __old = _M_fill;
> _M_fill = __ch;
> +   _M_fill_init = true;
> return __old;
>}
>
> diff --git a/libstdc++-v3/include/bits/basic_ios.tcc 
> b/libstdc++-v3/include/bits/basic_ios.tcc
> index a9313736e32..0197bdf8f67 100644
> --- a/libstdc++-v3/include/bits/basic_ios.tcc
> +++ b/libstdc++-v3/include/bits/basic_ios.tcc
> @@ -138,13 +138,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>// return without throwing an exception. Unfortunately,
>// ctype is not necessarily a required facet, so
>// streams with char_type != [char, wchar_t] will not have it by
> -  // default. Because of this, the correct value for _M_fill is
> -  // constructed on the first call of fill(). That way,
> +  // default. If the ctype facet is available now,
> +  // _M_fill is set here, but otherwise no fill

[gcc r15-510] libstdc++: Fix data race in std::basic_ios::fill() [PR77704]

2024-05-15 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:23ef0f68ad5fca1fd7027c5f6cb9f6d27b28

commit r15-510-g23ef0f68ad5fca1fd7027c5f6cb9f6d27b28
Author: Jonathan Wakely 
Date:   Fri May 3 20:00:08 2024 +0100

libstdc++: Fix data race in std::basic_ios::fill() [PR77704]

The lazy caching in std::basic_ios::fill() updates a mutable member
without synchronization, which can cause a data race if two threads both
call fill() on the same stream object when _M_fill_init is false.

To avoid this we can just cache the _M_fill member and set _M_fill_init
early in std::basic_ios::init, instead of doing it lazily. As explained
by the comment in init, there's a good reason for doing it lazily. When
char_type is neither char nor wchar_t, the locale might not have a
std::ctype facet, so getting the fill character would throw
an exception. The current lazy init allows using unformatted I/O with
such a stream, because the fill character is never needed and so it
doesn't matter if the locale doesn't have a ctype facet. We
can maintain this property by only setting the fill character in
std::basic_ios::init if the ctype facet is present at that time. If
fill() is called later and the fill character wasn't set by init, we can
get it from the stream's current locale at the point when fill() is
called (and not try to cache it without synchronization). If the stream
hasn't been imbued with a locale that includes the facet when we need
the fill() character, then throw bad_cast at that point.

This causes a change in behaviour for the following program:

  std::ostringstream out;
  out.imbue(loc);
  auto fill = out.fill();

Previously the fill character would have been set when fill() is called,
and so would have used the new locale. This commit changes it so that
the fill character is set on construction and isn't affected by the new
locale being imbued later. This new behaviour seems to be what the
standard requires, and matches MSVC.

The new 27_io/basic_ios/fill/char/fill.cc test verifies that it's still
possible to use a std::basic_ios without the ctype facet
being present at construction.

libstdc++-v3/ChangeLog:

PR libstdc++/77704
* include/bits/basic_ios.h (basic_ios::fill()): Do not modify
_M_fill and _M_fill_init in a const member function.
(basic_ios::fill(char_type)): Use _M_fill directly instead of
calling fill(). Set _M_fill_init to true.
* include/bits/basic_ios.tcc (basic_ios::init): Set _M_fill and
_M_fill_init here instead.
* testsuite/27_io/basic_ios/fill/char/1.cc: New test.
* testsuite/27_io/basic_ios/fill/wchar_t/1.cc: New test.

Diff:
---
 libstdc++-v3/include/bits/basic_ios.h  | 10 ++-
 libstdc++-v3/include/bits/basic_ios.tcc| 15 +++--
 .../testsuite/27_io/basic_ios/fill/char/1.cc   | 78 ++
 .../testsuite/27_io/basic_ios/fill/wchar_t/1.cc| 55 +++
 4 files changed, 148 insertions(+), 10 deletions(-)

diff --git a/libstdc++-v3/include/bits/basic_ios.h 
b/libstdc++-v3/include/bits/basic_ios.h
index 258e6042b8f7..bc3be4d2e371 100644
--- a/libstdc++-v3/include/bits/basic_ios.h
+++ b/libstdc++-v3/include/bits/basic_ios.h
@@ -373,11 +373,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   char_type
   fill() const
   {
-   if (!_M_fill_init)
- {
-   _M_fill = this->widen(' ');
-   _M_fill_init = true;
- }
+   if (__builtin_expect(!_M_fill_init, false))
+ return this->widen(' ');
return _M_fill;
   }
 
@@ -393,8 +390,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   char_type
   fill(char_type __ch)
   {
-   char_type __old = this->fill();
+   char_type __old = _M_fill;
_M_fill = __ch;
+   _M_fill_init = true;
return __old;
   }
 
diff --git a/libstdc++-v3/include/bits/basic_ios.tcc 
b/libstdc++-v3/include/bits/basic_ios.tcc
index a9313736e327..0197bdf8f671 100644
--- a/libstdc++-v3/include/bits/basic_ios.tcc
+++ b/libstdc++-v3/include/bits/basic_ios.tcc
@@ -138,13 +138,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // return without throwing an exception. Unfortunately,
   // ctype is not necessarily a required facet, so
   // streams with char_type != [char, wchar_t] will not have it by
-  // default. Because of this, the correct value for _M_fill is
-  // constructed on the first call of fill(). That way,
+  // default. If the ctype facet is available now,
+  // _M_fill is set here, but otherwise no fill character will be
+  // cached and a call to fill() will check for the facet again later
+  // (and will throw if the facet is still not present). This way
   // unformatted input and output with non-required basic_ios
   // instantiations is possible even withou

Re: [PATCH] libstdc++: Rewrite std::variant comparisons without macros

2024-05-15 Thread Jonathan Wakely
On Tue, 7 May 2024 at 14:51, Ville Voutilainen
 wrote:
>
> On Tue, 7 May 2024 at 16:47, Jonathan Wakely  wrote:
> >
> > I don't think using a macro for these really saves us much, we can do
> > this to avoid duplication instead. And now it's not a big, multi-line
> > macro that's a pain to edit.
> >
> > Any objections?
>
> No, that's beautiful, ship it.

Pushed to trunk.



[gcc r15-503] libstdc++: Rewrite std::variant comparisons without macros

2024-05-15 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:d08247b77831c496277b266807d4bd17656d1654

commit r15-503-gd08247b77831c496277b266807d4bd17656d1654
Author: Jonathan Wakely 
Date:   Tue Apr 2 19:40:51 2024 +0100

libstdc++: Rewrite std::variant comparisons without macros

libstdc++-v3/ChangeLog:

* include/std/variant (__detail::__variant::__compare): New
function template.
(operator==, operator!=, operator<, operator>, operator<=)
(operator>=): Replace macro definition with handwritten function
calling __detail::__variant::__compare.
(operator<=>): Call __detail::__variant::__compare.

Diff:
---
 libstdc++-v3/include/std/variant | 163 +++
 1 file changed, 112 insertions(+), 51 deletions(-)

diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant
index bf05eec9a6bf..cfb4bcdbcc98 100644
--- a/libstdc++-v3/include/std/variant
+++ b/libstdc++-v3/include/std/variant
@@ -48,6 +48,7 @@
 #include 
 #include  // in_place_index_t
 #if __cplusplus >= 202002L
+# include 
 # include 
 #endif
 
@@ -1237,47 +1238,119 @@ namespace __variant
 
   struct monostate { };
 
+namespace __detail::__variant
+{
+  template
+constexpr _Ret
+__compare(_Ret __ret, const _Vp& __lhs, const _Vp& __rhs, _Op __op)
+{
+  __variant::__raw_idx_visit(
+   [&__ret, &__lhs, __op] (auto&& __rhs_mem, auto __rhs_index) mutable
+   {
+ if constexpr (__rhs_index != variant_npos)
+   {
+ if (__lhs.index() == __rhs_index.value)
+   {
+ auto& __this_mem = std::get<__rhs_index>(__lhs);
+ __ret = __op(__this_mem, __rhs_mem);
+ return;
+   }
+   }
+ __ret = __op(__lhs.index() + 1, __rhs_index + 1);
+   }, __rhs);
+  return __ret;
+}
+} // namespace __detail::__variant
+
+  template
 #if __cpp_lib_concepts
-# define _VARIANT_RELATION_FUNCTION_CONSTRAINTS(TYPES, OP) \
-  requires ((requires (const TYPES& __t) { \
-   { __t OP __t } -> __detail::__boolean_testable; }) && ...)
-#else
-# define _VARIANT_RELATION_FUNCTION_CONSTRAINTS(TYPES, OP)
+requires ((requires (const _Types& __t) {
+  { __t == __t } -> convertible_to; }) && ...)
 #endif
+constexpr bool
+operator== [[nodiscard]] (const variant<_Types...>& __lhs,
+ const variant<_Types...>& __rhs)
+{
+  return __detail::__variant::__compare(true, __lhs, __rhs,
+   [](auto&& __l, auto&& __r) {
+ return __l == __r;
+   });
+}
 
-#define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP) \
-  template \
-_VARIANT_RELATION_FUNCTION_CONSTRAINTS(_Types, __OP) \
-constexpr bool \
-operator __OP [[nodiscard]] (const variant<_Types...>& __lhs, \
-const variant<_Types...>& __rhs) \
-{ \
-  bool __ret = true; \
-  __detail::__variant::__raw_idx_visit( \
-[&__ret, &__lhs] (auto&& __rhs_mem, auto __rhs_index) mutable \
-{ \
- if constexpr (__rhs_index != variant_npos) \
-   { \
- if (__lhs.index() == __rhs_index) \
-   { \
- auto& __this_mem = std::get<__rhs_index>(__lhs);  \
-  __ret = __this_mem __OP __rhs_mem; \
- return; \
-} \
-} \
- __ret = (__lhs.index() + 1) __OP (__rhs_index + 1); \
-   }, __rhs); \
-  return __ret; \
+  template
+#if __cpp_lib_concepts
+requires ((requires (const _Types& __t) {
+  { __t != __t } -> convertible_to; }) && ...)
+#endif
+constexpr bool
+operator!= [[nodiscard]] (const variant<_Types...>& __lhs,
+ const variant<_Types...>& __rhs)
+{
+  return __detail::__variant::__compare(true, __lhs, __rhs,
+   [](auto&& __l, auto&& __r) {
+ return __l != __r;
+   });
 }
 
-  _VARIANT_RELATION_FUNCTION_TEMPLATE(<)
-  _VARIANT_RELATION_FUNCTION_TEMPLATE(<=)
-  _VARIANT_RELATION_FUNCTION_TEMPLATE(==)
-  _VARIANT_RELATION_FUNCTION_TEMPLATE(!=)
-  _VARIANT_RELATION_FUNCTION_TEMPLATE(>=)
-  _VARIANT_RELATION_FUNCTION_TEMPLATE(>)
+  template
+#if __cpp_lib_concepts
+requires ((requires (const _Types& __t) {
+  { __t < __t } -> convertible_to; }) && ...)
+#endif
+constexpr bool
+operator< [[nodiscard]] (const variant<_Types...>& __lhs,
+const variant<_Types...>& __rhs)
+ 

[committed] libstdc++: Give std::memory_order a fixed underlying type [PR89624]

2024-05-15 Thread Jonathan Wakely
Tested x86_64-linux. Pushed to trunk.

-- >8 --

Prior to C++20 this enum type doesn't have a fixed underlying type,
which means it can be modified by -fshort-enums, which then means the
HLE bits are outside the range of valid values for the type.

As it has a fixed type of int in C++20 and later, do the same for
earlier standards too. This is technically a change for C++17 down,
because the implicit underlying type (without -fshort-enums) was
unsigned before. I doubt it matters in practice. That incompatibility
already exists between C++17 and C++20 and nobody has noticed or
complained. Now at least the underlying type will be int for all -std
modes.

libstdc++-v3/ChangeLog:

PR libstdc++/89624
* include/bits/atomic_base.h (memory_order): Use int as
underlying type.
* testsuite/29_atomics/atomic/89624.cc: New test.
---
 libstdc++-v3/include/bits/atomic_base.h   | 4 ++--
 libstdc++-v3/testsuite/29_atomics/atomic/89624.cc | 9 +
 2 files changed, 11 insertions(+), 2 deletions(-)
 create mode 100644 libstdc++-v3/testsuite/29_atomics/atomic/89624.cc

diff --git a/libstdc++-v3/include/bits/atomic_base.h 
b/libstdc++-v3/include/bits/atomic_base.h
index dd360302f80..062f1549740 100644
--- a/libstdc++-v3/include/bits/atomic_base.h
+++ b/libstdc++-v3/include/bits/atomic_base.h
@@ -78,7 +78,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   inline constexpr memory_order memory_order_acq_rel = memory_order::acq_rel;
   inline constexpr memory_order memory_order_seq_cst = memory_order::seq_cst;
 #else
-  typedef enum memory_order
+  enum memory_order : int
 {
   memory_order_relaxed,
   memory_order_consume,
@@ -86,7 +86,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   memory_order_release,
   memory_order_acq_rel,
   memory_order_seq_cst
-} memory_order;
+};
 #endif
 
   /// @cond undocumented
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic/89624.cc 
b/libstdc++-v3/testsuite/29_atomics/atomic/89624.cc
new file mode 100644
index 000..480f7c65e2d
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic/89624.cc
@@ -0,0 +1,9 @@
+// { dg-options "-fshort-enums" }
+// { dg-do compile { target c++11 } }
+
+// Bug 89624 HLE bits don't work with -fshort-enums or -fstrict-enums
+
+#include 
+
+static_assert((std::memory_order_acquire | std::__memory_order_hle_acquire)
+!= std::memory_order_acquire, "HLE acquire sets a bit");
-- 
2.44.0



[gcc r15-502] libstdc++: Give std::memory_order a fixed underlying type [PR89624]

2024-05-15 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:99dd1be14172445795f0012b935359e7014a2215

commit r15-502-g99dd1be14172445795f0012b935359e7014a2215
Author: Jonathan Wakely 
Date:   Thu Apr 11 19:12:48 2024 +0100

libstdc++: Give std::memory_order a fixed underlying type [PR89624]

Prior to C++20 this enum type doesn't have a fixed underlying type,
which means it can be modified by -fshort-enums, which then means the
HLE bits are outside the range of valid values for the type.

As it has a fixed type of int in C++20 and later, do the same for
earlier standards too. This is technically a change for C++17 down,
because the implicit underlying type (without -fshort-enums) was
unsigned before. I doubt it matters in practice. That incompatibility
already exists between C++17 and C++20 and nobody has noticed or
complained. Now at least the underlying type will be int for all -std
modes.

libstdc++-v3/ChangeLog:

PR libstdc++/89624
* include/bits/atomic_base.h (memory_order): Use int as
underlying type.
* testsuite/29_atomics/atomic/89624.cc: New test.

Diff:
---
 libstdc++-v3/include/bits/atomic_base.h   | 4 ++--
 libstdc++-v3/testsuite/29_atomics/atomic/89624.cc | 9 +
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/bits/atomic_base.h 
b/libstdc++-v3/include/bits/atomic_base.h
index dd360302f801..062f15497403 100644
--- a/libstdc++-v3/include/bits/atomic_base.h
+++ b/libstdc++-v3/include/bits/atomic_base.h
@@ -78,7 +78,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   inline constexpr memory_order memory_order_acq_rel = memory_order::acq_rel;
   inline constexpr memory_order memory_order_seq_cst = memory_order::seq_cst;
 #else
-  typedef enum memory_order
+  enum memory_order : int
 {
   memory_order_relaxed,
   memory_order_consume,
@@ -86,7 +86,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   memory_order_release,
   memory_order_acq_rel,
   memory_order_seq_cst
-} memory_order;
+};
 #endif
 
   /// @cond undocumented
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic/89624.cc 
b/libstdc++-v3/testsuite/29_atomics/atomic/89624.cc
new file mode 100644
index ..480f7c65e2d7
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic/89624.cc
@@ -0,0 +1,9 @@
+// { dg-options "-fshort-enums" }
+// { dg-do compile { target c++11 } }
+
+// Bug 89624 HLE bits don't work with -fshort-enums or -fstrict-enums
+
+#include 
+
+static_assert((std::memory_order_acquire | std::__memory_order_hle_acquire)
+!= std::memory_order_acquire, "HLE acquire sets a bit");


[gcc r14-10208] libstdc++: Guard dynamic_cast use in src/c++23/print.cc [PR115015]

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

commit r14-10208-geefa4c06483f95f5076687ed6aae5c6001731164
Author: Jonathan Wakely 
Date:   Tue May 14 14:32:23 2024 +0100

libstdc++: Guard dynamic_cast use in src/c++23/print.cc [PR115015]

Do not use dynamic_cast unconditionally, in case libstdc++ is built with
-fno-rtti.

libstdc++-v3/ChangeLog:

PR libstdc++/115015
* src/c++23/print.cc (__open_terminal(streambuf*)) [!__cpp_rtti]:
Do not use dynamic_cast.

Diff:
---
 libstdc++-v3/src/c++23/print.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/src/c++23/print.cc b/libstdc++-v3/src/c++23/print.cc
index aceca6f9139b..99a19cd45002 100644
--- a/libstdc++-v3/src/c++23/print.cc
+++ b/libstdc++-v3/src/c++23/print.cc
@@ -87,7 +87,7 @@ namespace
   void*
   __open_terminal(std::streambuf* sb)
   {
-#ifndef _GLIBCXX_USE_STDIO_PURE
+#if ! defined _GLIBCXX_USE_STDIO_PURE && defined __cpp_rtti
 using namespace __gnu_cxx;
 
 if (auto fb = dynamic_cast*>(sb))


[committed] libstdc++: Guard dynamic_cast use in src/c++23/print.cc [PR115015]

2024-05-14 Thread Jonathan Wakely
Tested x86_64-linux, x86_64-w64-mingw32. Pushed to trunk. Backport to
gcc-14 to follow.

-- >8 --

Do not use dynamic_cast unconditionally, in case libstdc++ is built with
-fno-rtti.

libstdc++-v3/ChangeLog:

PR libstdc++/115015
* src/c++23/print.cc (__open_terminal(streambuf*)) [!__cpp_rtti]:
Do not use dynamic_cast.
---
 libstdc++-v3/src/c++23/print.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/src/c++23/print.cc b/libstdc++-v3/src/c++23/print.cc
index aceca6f9139..99a19cd4500 100644
--- a/libstdc++-v3/src/c++23/print.cc
+++ b/libstdc++-v3/src/c++23/print.cc
@@ -87,7 +87,7 @@ namespace
   void*
   __open_terminal(std::streambuf* sb)
   {
-#ifndef _GLIBCXX_USE_STDIO_PURE
+#if ! defined _GLIBCXX_USE_STDIO_PURE && defined __cpp_rtti
 using namespace __gnu_cxx;
 
 if (auto fb = dynamic_cast*>(sb))
-- 
2.44.0



[gcc r15-485] libstdc++: Guard dynamic_cast use in src/c++23/print.cc [PR115015]

2024-05-14 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:6cc8698244b522ad079675022c9de9e40de85878

commit r15-485-g6cc8698244b522ad079675022c9de9e40de85878
Author: Jonathan Wakely 
Date:   Tue May 14 14:32:23 2024 +0100

libstdc++: Guard dynamic_cast use in src/c++23/print.cc [PR115015]

Do not use dynamic_cast unconditionally, in case libstdc++ is built with
-fno-rtti.

libstdc++-v3/ChangeLog:

PR libstdc++/115015
* src/c++23/print.cc (__open_terminal(streambuf*)) [!__cpp_rtti]:
Do not use dynamic_cast.

Diff:
---
 libstdc++-v3/src/c++23/print.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/src/c++23/print.cc b/libstdc++-v3/src/c++23/print.cc
index aceca6f9139b..99a19cd45002 100644
--- a/libstdc++-v3/src/c++23/print.cc
+++ b/libstdc++-v3/src/c++23/print.cc
@@ -87,7 +87,7 @@ namespace
   void*
   __open_terminal(std::streambuf* sb)
   {
-#ifndef _GLIBCXX_USE_STDIO_PURE
+#if ! defined _GLIBCXX_USE_STDIO_PURE && defined __cpp_rtti
 using namespace __gnu_cxx;
 
 if (auto fb = dynamic_cast*>(sb))


[committed] libstdc++: Document when std::string::shrink_to_fit was added

2024-05-14 Thread Jonathan Wakely
Pushed to trunk.

-- >8 --

This section can be misread to say that shrink_to_fit is available from
GCC 3.4, but it was added later.

libstdc++-v3/ChangeLog:

* doc/xml/manual/strings.xml: Clarify that GCC 4.5 added
std::string::shrink_to_fit.
* doc/html/manual/strings.html: Regenerate.
---
 libstdc++-v3/doc/html/manual/strings.html | 4 ++--
 libstdc++-v3/doc/xml/manual/strings.xml   | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/libstdc++-v3/doc/html/manual/strings.html 
b/libstdc++-v3/doc/html/manual/strings.html
index ceb09f97eac..34a34dfa980 100644
--- a/libstdc++-v3/doc/html/manual/strings.html
+++ b/libstdc++-v3/doc/html/manual/strings.html
@@ -269,8 +269,8 @@ stringtok(Container container, string const in,
   (see this FAQ
   entry) but the regular copy constructor cannot be used
   because libstdc++'s string is Copy-On-Write in 
GCC 3.
-   In C++11 mode you can call
-  s.shrink_to_fit() to achieve the same effect as
+   From GCC 4.5 in C++11 mode you
+  can call s.shrink_to_fit() to achieve the same 
effect as
   s.reserve(s.size()).
CString 
(MFC)
 A common lament seen in various newsgroups deals with the Standard
diff --git a/libstdc++-v3/doc/xml/manual/strings.xml 
b/libstdc++-v3/doc/xml/manual/strings.xml
index b0dab645a2d..4a63dd96477 100644
--- a/libstdc++-v3/doc/xml/manual/strings.xml
+++ b/libstdc++-v3/doc/xml/manual/strings.xml
@@ -356,8 +356,8 @@ stringtok(Container container, string const in,
   entry) but the regular copy constructor cannot be used
   because libstdc++'s string is Copy-On-Write in GCC 3.

-   In C++11 mode you can call
-  s.shrink_to_fit() to achieve the same effect as
+   From GCC 4.5 in C++11 mode you
+  can call s.shrink_to_fit() to achieve the same effect as
   s.reserve(s.size()).

 
-- 
2.44.0



[gcc r15-484] libstdc++: Document when std::string::shrink_to_fit was added

2024-05-14 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:0a99ad5c52caa06c113b1889bbe6634812b89be5

commit r15-484-g0a99ad5c52caa06c113b1889bbe6634812b89be5
Author: Jonathan Wakely 
Date:   Tue May 14 14:28:21 2024 +0100

libstdc++: Document when std::string::shrink_to_fit was added

This section can be misread to say that shrink_to_fit is available from
GCC 3.4, but it was added later.

libstdc++-v3/ChangeLog:

* doc/xml/manual/strings.xml: Clarify that GCC 4.5 added
std::string::shrink_to_fit.
* doc/html/manual/strings.html: Regenerate.

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

diff --git a/libstdc++-v3/doc/html/manual/strings.html 
b/libstdc++-v3/doc/html/manual/strings.html
index ceb09f97eac4..34a34dfa980c 100644
--- a/libstdc++-v3/doc/html/manual/strings.html
+++ b/libstdc++-v3/doc/html/manual/strings.html
@@ -269,8 +269,8 @@ stringtok(Container container, string const in,
   (see this FAQ
   entry) but the regular copy constructor cannot be used
   because libstdc++'s string is Copy-On-Write in 
GCC 3.
-   In C++11 mode you can call
-  s.shrink_to_fit() to achieve the same effect as
+   From GCC 4.5 in C++11 mode you
+  can call s.shrink_to_fit() to achieve the same 
effect as
   s.reserve(s.size()).
CString 
(MFC)
 A common lament seen in various newsgroups deals with the Standard
diff --git a/libstdc++-v3/doc/xml/manual/strings.xml 
b/libstdc++-v3/doc/xml/manual/strings.xml
index b0dab645a2d9..4a63dd964771 100644
--- a/libstdc++-v3/doc/xml/manual/strings.xml
+++ b/libstdc++-v3/doc/xml/manual/strings.xml
@@ -356,8 +356,8 @@ stringtok(Container container, string const in,
   entry) but the regular copy constructor cannot be used
   because libstdc++'s string is Copy-On-Write in GCC 3.

-   In C++11 mode you can call
-  s.shrink_to_fit() to achieve the same effect as
+   From GCC 4.5 in C++11 mode you
+  can call s.shrink_to_fit() to achieve the same effect as
   s.reserve(s.size()).



[committed] libstdc++: Fix typo in std::stacktrace::max_size [PR115063]

2024-05-14 Thread Jonathan Wakely
Tested x86_64-linux. Pushed to trunk, gcc14 and gcc-13.

-- >8 --

libstdc++-v3/ChangeLog:

PR libstdc++/115063
* include/std/stacktrace (basic_stacktrace::max_size): Fix typo
in reference to _M_alloc member.
* testsuite/19_diagnostics/stacktrace/stacktrace.cc: Check
max_size() compiles.
---
 libstdc++-v3/include/std/stacktrace|  2 +-
 .../testsuite/19_diagnostics/stacktrace/stacktrace.cc  | 10 ++
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/stacktrace 
b/libstdc++-v3/include/std/stacktrace
index 92a69a53d98..d217d63af3b 100644
--- a/libstdc++-v3/include/std/stacktrace
+++ b/libstdc++-v3/include/std/stacktrace
@@ -430,7 +430,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   [[nodiscard]]
   size_type
   max_size() const noexcept
-  { return _Impl::_S_max_size(_M_impl._M_alloc); }
+  { return _Impl::_S_max_size(_M_alloc); }
 
   [[nodiscard]]
   const_reference
diff --git a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc 
b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc
index 070c4157471..a49cddfef26 100644
--- a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc
+++ b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc
@@ -206,10 +206,20 @@ test_pr105031()
   s = auto(s);
 }
 
+void
+test_pr115063()
+{
+  // PR libstdc++/115063
+  // compilation error: std::basic_stracktrace::max_size()
+  std::stacktrace s;
+  VERIFY( s.max_size() != 0 );
+}
+
 int main()
 {
   test_cons();
   test_assign();
   test_swap();
   test_pr105031();
+  test_pr115063();
 }
-- 
2.44.0



[gcc r15-481] libstdc++: Fix typo in std::stacktrace::max_size [PR115063]

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

commit r15-481-gccc26a1af07b34ce2e7d3b2497f27992d1b1bbc2
Author: Jonathan Wakely 
Date:   Mon May 13 16:25:13 2024 +0100

libstdc++: Fix typo in std::stacktrace::max_size [PR115063]

libstdc++-v3/ChangeLog:

PR libstdc++/115063
* include/std/stacktrace (basic_stacktrace::max_size): Fix typo
in reference to _M_alloc member.
* testsuite/19_diagnostics/stacktrace/stacktrace.cc: Check
max_size() compiles.

Diff:
---
 libstdc++-v3/include/std/stacktrace|  2 +-
 libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc | 10 ++
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/stacktrace 
b/libstdc++-v3/include/std/stacktrace
index 92a69a53d986..d217d63af3bb 100644
--- a/libstdc++-v3/include/std/stacktrace
+++ b/libstdc++-v3/include/std/stacktrace
@@ -430,7 +430,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   [[nodiscard]]
   size_type
   max_size() const noexcept
-  { return _Impl::_S_max_size(_M_impl._M_alloc); }
+  { return _Impl::_S_max_size(_M_alloc); }
 
   [[nodiscard]]
   const_reference
diff --git a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc 
b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc
index 070c4157471c..a49cddfef268 100644
--- a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc
+++ b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc
@@ -206,10 +206,20 @@ test_pr105031()
   s = auto(s);
 }
 
+void
+test_pr115063()
+{
+  // PR libstdc++/115063
+  // compilation error: std::basic_stracktrace::max_size()
+  std::stacktrace s;
+  VERIFY( s.max_size() != 0 );
+}
+
 int main()
 {
   test_cons();
   test_assign();
   test_swap();
   test_pr105031();
+  test_pr115063();
 }


[gcc r13-8772] libstdc++: Fix typo in std::stacktrace::max_size [PR115063]

2024-05-14 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:7dca716decf5a07f903610fda9457ff0422d2758

commit r13-8772-g7dca716decf5a07f903610fda9457ff0422d2758
Author: Jonathan Wakely 
Date:   Mon May 13 16:25:13 2024 +0100

libstdc++: Fix typo in std::stacktrace::max_size [PR115063]

libstdc++-v3/ChangeLog:

PR libstdc++/115063
* include/std/stacktrace (basic_stacktrace::max_size): Fix typo
in reference to _M_alloc member.
* testsuite/19_diagnostics/stacktrace/stacktrace.cc: Check
max_size() compiles.

(cherry picked from commit dd9677f3343ca2a4b4aab9428b8129774accac29)

Diff:
---
 libstdc++-v3/include/std/stacktrace|  2 +-
 libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc | 10 ++
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/stacktrace 
b/libstdc++-v3/include/std/stacktrace
index e4ca2d6bfa99..8f09467d7512 100644
--- a/libstdc++-v3/include/std/stacktrace
+++ b/libstdc++-v3/include/std/stacktrace
@@ -483,7 +483,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   size_type
   max_size() const noexcept
-  { return _Impl::_S_max_size(_M_impl._M_alloc); }
+  { return _Impl::_S_max_size(_M_alloc); }
 
   const_reference
   operator[](size_type __n) const noexcept
diff --git a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc 
b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc
index 0a358b7b8ff7..1caa0fd35cb5 100644
--- a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc
+++ b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc
@@ -206,10 +206,20 @@ test_pr105031()
   s = auto(s);
 }
 
+void
+test_pr115063()
+{
+  // PR libstdc++/115063
+  // compilation error: std::basic_stracktrace::max_size()
+  std::stacktrace s;
+  VERIFY( s.max_size() != 0 );
+}
+
 int main()
 {
   test_cons();
   test_assign();
   test_swap();
   test_pr105031();
+  test_pr115063();
 }


[gcc r13-8771] libstdc++: Fix infinite loop in std::binomial_distribution [PR114359]

2024-05-14 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:71e941b0e329d3a316e465569c92e08788a68614

commit r13-8771-g71e941b0e329d3a316e465569c92e08788a68614
Author: Jonathan Wakely 
Date:   Mon Mar 18 13:22:17 2024 +

libstdc++: Fix infinite loop in std::binomial_distribution [PR114359]

The multiplication (4 * _M_t * __1p) can wraparound to zero if _M_t is
unsigned and 4 * _M_t wraps to zero. The third operand has type double,
so do the second multiplication first, so that we aren't multiplying
integers.

libstdc++-v3/ChangeLog:

PR libstdc++/114359
* include/bits/random.tcc (binomial_distribution::param_type):
Ensure arithmetic is done as type double.
* testsuite/26_numerics/random/binomial_distribution/114359.cc: New 
test.

(cherry picked from commit 07e03761a7fc1626a6a74ed957e117f56981558c)

Diff:
---
 libstdc++-v3/include/bits/random.tcc |  2 +-
 .../26_numerics/random/binomial_distribution/114359.cc   | 12 
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/bits/random.tcc 
b/libstdc++-v3/include/bits/random.tcc
index 6afddbbdd467..9e9c98e6826f 100644
--- a/libstdc++-v3/include/bits/random.tcc
+++ b/libstdc++-v3/include/bits/random.tcc
@@ -1503,7 +1503,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  // sqrt(pi / 2)
  const double __spi_2 = 1.2533141373155002512078826424055226L;
  _M_s1 = std::sqrt(__np * __1p) * (1 + _M_d1 / (4 * __np));
- _M_s2 = std::sqrt(__np * __1p) * (1 + _M_d2 / (4 * _M_t * __1p));
+ _M_s2 = std::sqrt(__np * __1p) * (1 + _M_d2 / (4 * (_M_t * __1p)));
  _M_c = 2 * _M_d1 / __np;
  _M_a1 = std::exp(_M_c) * _M_s1 * __spi_2;
  const double __a12 = _M_a1 + _M_s2 * __spi_2;
diff --git 
a/libstdc++-v3/testsuite/26_numerics/random/binomial_distribution/114359.cc 
b/libstdc++-v3/testsuite/26_numerics/random/binomial_distribution/114359.cc
new file mode 100644
index ..c1e4c380bf91
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/random/binomial_distribution/114359.cc
@@ -0,0 +1,12 @@
+// { dg-do run { target c++11 } }
+
+// Bug 114359 - std::binomial_distribution hangs in infinite loop
+
+#include 
+
+int main()
+{
+  std::default_random_engine g{};
+  std::binomial_distribution b(1U << 30);
+  b(g);  // hangs forever
+}


[gcc r13-8770] libstdc++: Adjust expected locale-dependent date formats in tests

2024-05-14 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:b9e2a3227359f20a6e3501e02ae5f909f7f96b8a

commit r13-8770-gb9e2a3227359f20a6e3501e02ae5f909f7f96b8a
Author: Jonathan Wakely 
Date:   Wed Apr 10 13:24:51 2024 +0100

libstdc++: Adjust expected locale-dependent date formats in tests

The std/time/year_month_day/io.cc test assumes that %x in the fr_FR
locale is %d/%m/%Y but on FreeBSD it is %d.%m.%Y instead. Make the test
PASS for either format.

Similarly, 27_io/manipulators/extended/get_time/char/2.cc expects that
%a in the de_DE locale is "Di" but on FreeBSD it's "Di." with a trailing
period. Adjust the input string to be "1971 Di." instead of "Di 1971"
and that way if %a doesn't expect the trailing '.' it simply won't
extract it from the stream.

This fixes:
FAIL: std/time/year_month_day/io.cc  -std=gnu++20 execution test
FAIL: 27_io/manipulators/extended/get_time/char/2.cc  -std=gnu++17 
execution test

libstdc++-v3/ChangeLog:

* testsuite/27_io/manipulators/extended/get_time/char/2.cc:
Adjust input string so that it matches %a with or without a
trailing period.
* testsuite/std/time/year_month_day/io.cc: Adjust expected
format for %x in the fr_FR locale.

(cherry picked from commit 4decc1062f0f6eb44209d9d5a26a744ffa474648)

Diff:
---
 .../testsuite/27_io/manipulators/extended/get_time/char/2.cc| 6 +++---
 libstdc++-v3/testsuite/std/time/year_month_day/io.cc| 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git 
a/libstdc++-v3/testsuite/27_io/manipulators/extended/get_time/char/2.cc 
b/libstdc++-v3/testsuite/27_io/manipulators/extended/get_time/char/2.cc
index b99264012879..1de9eadc9e7e 100644
--- a/libstdc++-v3/testsuite/27_io/manipulators/extended/get_time/char/2.cc
+++ b/libstdc++-v3/testsuite/27_io/manipulators/extended/get_time/char/2.cc
@@ -35,9 +35,9 @@ void test01()
   VERIFY( loc_de != loc_c );
   istringstream iss;
   iss.imbue(loc_de);
-  iss.str("Di 1971");
-  tm time1;
-  iss >> get_time(, "%a %Y");
+  iss.str("1971 Di."); // %a is "Di" on some targets, "Di." on others.
+  tm time1{};
+  iss >> get_time(, "%Y %a");
   VERIFY(time1.tm_wday == 2);
   VERIFY(time1.tm_year == 71);
 }
diff --git a/libstdc++-v3/testsuite/std/time/year_month_day/io.cc 
b/libstdc++-v3/testsuite/std/time/year_month_day/io.cc
index 04e6e59c8f76..0efa25a61425 100644
--- a/libstdc++-v3/testsuite/std/time/year_month_day/io.cc
+++ b/libstdc++-v3/testsuite/std/time/year_month_day/io.cc
@@ -85,7 +85,7 @@ test_format()
   s = std::format(loc_fr, "{:%x}", 2022y/December/19);
   VERIFY( s == "12/19/22" );
   s = std::format(loc_fr, "{:L%x}", 2022y/December/19);
-  VERIFY( s == "19/12/2022" );
+  VERIFY( s == "19/12/2022" || s == "19.12.2022" ); // depends on locale defs
   s = std::format(loc_fr, "{}", 2022y/December/19);
   VERIFY( s == "2022-12-19" );
   s = std::format(loc_fr, "{:L%F}", 2022y/December/19);


[gcc r13-8769] libstdc++: Fix typo in Doxygen comment

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

commit r13-8769-gebc61a9c4c730bf5562db25b1fcc06d615e33e66
Author: Jonathan Wakely 
Date:   Thu Apr 25 13:52:00 2024 +0100

libstdc++: Fix typo in Doxygen comment

libstdc++-v3/ChangeLog:

* include/std/chrono (tzdb_list): Fix typo in Doxygen comment.

(cherry picked from commit 6391cf8bd9c1d71805d9aba00b25fdaa550f39c8)

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

diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono
index edb782f6f10e..1f3f897d932a 100644
--- a/libstdc++-v3/include/std/chrono
+++ b/libstdc++-v3/include/std/chrono
@@ -2790,7 +2790,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   /** Remove the tzdb object _after_ the one the iterator refers to.
*
-   * Calling this function concurently with any of `front()`, `begin()`,
+   * Calling this function concurrently with any of `front()`, `begin()`,
* or `end()` does not cause a data race, but in general this function
* is not thread-safe. The behaviour may be undefined if erasing an
* element from the list while another thread is calling the same


[gcc r13-8768] libstdc++: Fix run_doxygen for Doxygen 1.10 man page format

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

commit r13-8768-gbce15a5d7d2c4053b8d5e718f00db8eb20116cb6
Author: Jonathan Wakely 
Date:   Thu Apr 25 13:24:56 2024 +0100

libstdc++: Fix run_doxygen for Doxygen 1.10 man page format

Doxygen switched from \fC to \fR in its man page output:
https://github.com/doxygen/doxygen/pull/10497

This breaks our script that expects \fC so change the regaulr expression
to work with either style.

libstdc++-v3/ChangeLog:

* scripts/run_doxygen: Adjust sed pattern to match '\fR' for
new man output that Doxygen 1.10 generates.

(cherry picked from commit c9cc1c850c6d084752207b6cf247a0a48bae0d52)

Diff:
---
 libstdc++-v3/scripts/run_doxygen | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/scripts/run_doxygen b/libstdc++-v3/scripts/run_doxygen
index 42ed9eb4f5df..9c11a0cfa1fd 100644
--- a/libstdc++-v3/scripts/run_doxygen
+++ b/libstdc++-v3/scripts/run_doxygen
@@ -294,7 +294,11 @@ $gxx $cppflags $cxxflags 
${srcdir}/doc/doxygen/stdheader.cc -o ./stdheader || ex
 problematic=`grep -E -l '#include <.*h>' [a-z]*.3`
 for f in $problematic; do
 # this is also slow, but safe and easy to debug
-oldh=`sed -n '/fC#include .*/\1/p' $f`
+oldh=`sed -n '/f[CR]#include .*/\1/p' $f`
+if [ "$oldh" == "" ]; then
+  echo "ERROR: Doxygen man page formatting changed" 2>&1
+  continue
+fi
 newh=`echo $oldh | sed 's/&\\././g' | ./stdheader`
 sed "s=${oldh/\\/.}=${newh}=" $f > TEMP && mv TEMP $f
 done


[gcc r14-10207] libstdc++: Fix typo in std::stacktrace::max_size [PR115063]

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

commit r14-10207-gc60205cd4aeea586b7b1fe06baa9861b6d279648
Author: Jonathan Wakely 
Date:   Mon May 13 16:25:13 2024 +0100

libstdc++: Fix typo in std::stacktrace::max_size [PR115063]

libstdc++-v3/ChangeLog:

PR libstdc++/115063
* include/std/stacktrace (basic_stacktrace::max_size): Fix typo
in reference to _M_alloc member.
* testsuite/19_diagnostics/stacktrace/stacktrace.cc: Check
max_size() compiles.

(cherry picked from commit dd9677f3343ca2a4b4aab9428b8129774accac29)

Diff:
---
 libstdc++-v3/include/std/stacktrace|  2 +-
 libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc | 10 ++
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/stacktrace 
b/libstdc++-v3/include/std/stacktrace
index 92a69a53d986..d217d63af3bb 100644
--- a/libstdc++-v3/include/std/stacktrace
+++ b/libstdc++-v3/include/std/stacktrace
@@ -430,7 +430,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   [[nodiscard]]
   size_type
   max_size() const noexcept
-  { return _Impl::_S_max_size(_M_impl._M_alloc); }
+  { return _Impl::_S_max_size(_M_alloc); }
 
   [[nodiscard]]
   const_reference
diff --git a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc 
b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc
index 070c4157471c..a49cddfef268 100644
--- a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc
+++ b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc
@@ -206,10 +206,20 @@ test_pr105031()
   s = auto(s);
 }
 
+void
+test_pr115063()
+{
+  // PR libstdc++/115063
+  // compilation error: std::basic_stracktrace::max_size()
+  std::stacktrace s;
+  VERIFY( s.max_size() != 0 );
+}
+
 int main()
 {
   test_cons();
   test_assign();
   test_swap();
   test_pr105031();
+  test_pr115063();
 }


[gcc r14-10206] libstdc++: Guard uses of is_pointer_interconvertible_v [PR114891]

2024-05-14 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:4d3b358fd757ddd09cbee202f47939043c78676c

commit r14-10206-g4d3b358fd757ddd09cbee202f47939043c78676c
Author: Jonathan Wakely 
Date:   Tue Apr 30 09:48:00 2024 +0100

libstdc++: Guard uses of is_pointer_interconvertible_v [PR114891]

This type trait isn't supported by Clang 18. It's only used in static
assertions, so they can just be omitted if the trait isn't available.

libstdc++-v3/ChangeLog:

PR libstdc++/114891
* include/std/generator: Check feature test macro before using
is_pointer_interconvertible_v.

(cherry picked from commit 1fbe1a50d86df11f434351cf62461a32747f9710)

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

diff --git a/libstdc++-v3/include/std/generator 
b/libstdc++-v3/include/std/generator
index 789016b5a883..1d5acc914203 100644
--- a/libstdc++-v3/include/std/generator
+++ b/libstdc++-v3/include/std/generator
@@ -322,8 +322,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template
auto await_suspend(std::coroutine_handle<_Promise> __c) noexcept
{
+#ifdef __glibcxx_is_pointer_interconvertible
  static_assert(is_pointer_interconvertible_base_of_v<
_Promise_erased, _Promise>);
+#endif
 
  auto& __n = __c.promise()._M_nest;
  return __n._M_pop();
@@ -344,8 +346,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template
void await_suspend(std::coroutine_handle<_Promise>) noexcept
{
+#ifdef __glibcxx_is_pointer_interconvertible
  static_assert(is_pointer_interconvertible_base_of_v<
_Promise_erased, _Promise>);
+#endif
  _M_bottom_value = ::std::addressof(_M_value);
}
 
@@ -375,8 +379,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
std::coroutine_handle<>
await_suspend(std::coroutine_handle<_Promise> __p) noexcept
{
+#ifdef __glibcxx_is_pointer_interconvertible
  static_assert(is_pointer_interconvertible_base_of_v<
_Promise_erased, _Promise>);
+#endif
 
  auto __c = _Coro_handle::from_address(__p.address());
  auto __t = _Coro_handle::from_address(this->_M_gen._M_coro.address());
@@ -685,8 +691,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return { coroutine_handle::from_promise(*this) }; }
   };
 
+#ifdef __glibcxx_is_pointer_interconvertible
   static_assert(is_pointer_interconvertible_base_of_v<_Erased_promise,
promise_type>);
+#endif
 
   generator(const generator&) = delete;


[gcc r14-10204] libstdc++: Fix handling of incomplete UTF-8 sequences in _Unicode_view

2024-05-14 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:b0f022f93a710c8143badedf8110a47227e17f62

commit r14-10204-gb0f022f93a710c8143badedf8110a47227e17f62
Author: Jonathan Wakely 
Date:   Wed May 1 17:09:39 2024 +0100

libstdc++: Fix handling of incomplete UTF-8 sequences in _Unicode_view

Eddie Nolan reported to me that _Unicode_view was not correctly
implementing the substitution of ill-formed subsequences with U+FFFD,
due to failing to increment the counter when the iterator reaches the
end of the sequence before a multibyte sequence is complete.  As a
result, the incomplete sequence was not completely consumed, and then
the remaining character was treated as another ill-formed sequence,
giving two U+FFFD characters instead of one.

To avoid similar mistakes in future, this change introduces a lambda
that increments the iterator and the counter together. This ensures the
counter is always incremented when the iterator is incremented, so that
we always know how many characters have been consumed.

libstdc++-v3/ChangeLog:

* include/bits/unicode.h (_Unicode_view::_M_read_utf8): Ensure
count of characters consumed is correct when the end of the
input is reached unexpectedly.
* testsuite/ext/unicode/view.cc: Test incomplete UTF-8
sequences.

(cherry picked from commit 3f04f3939ea0ac8fdd766a60655d29de2ffb44e5)

Diff:
---
 libstdc++-v3/include/bits/unicode.h| 24 +++-
 libstdc++-v3/testsuite/ext/unicode/view.cc |  7 +++
 2 files changed, 18 insertions(+), 13 deletions(-)

diff --git a/libstdc++-v3/include/bits/unicode.h 
b/libstdc++-v3/include/bits/unicode.h
index 29813b743dc1..46238143fb61 100644
--- a/libstdc++-v3/include/bits/unicode.h
+++ b/libstdc++-v3/include/bits/unicode.h
@@ -261,9 +261,13 @@ namespace __unicode
   {
_Guard<_Iter> __g{this, _M_curr()};
char32_t __c{};
-   uint8_t __u = *_M_curr()++;
const uint8_t __lo_bound = 0x80, __hi_bound = 0xBF;
+   uint8_t __u = *_M_curr()++;
uint8_t __to_incr = 1;
+   auto __incr = [&, this] {
+ ++__to_incr;
+ return ++_M_curr();
+   };
 
if (__u <= 0x7F) [[likely]]  // 0x00 to 0x7F
  __c = __u;
@@ -281,8 +285,7 @@ namespace __unicode
else
  {
__c = (__c << 6) | (__u & 0x3F);
-   ++_M_curr();
-   ++__to_incr;
+   __incr();
  }
  }
else if (__u <= 0xEF) // 0xE0 to 0xEF
@@ -295,11 +298,10 @@ namespace __unicode
 
if (__u < __lo_bound_2 || __u > __hi_bound_2) [[unlikely]]
  __c = _S_error();
-   else if (++_M_curr() == _M_last) [[unlikely]]
+   else if (__incr() == _M_last) [[unlikely]]
  __c = _S_error();
else
  {
-   ++__to_incr;
__c = (__c << 6) | (__u & 0x3F);
__u = *_M_curr();
 
@@ -308,8 +310,7 @@ namespace __unicode
else
  {
__c = (__c << 6) | (__u & 0x3F);
-   ++_M_curr();
-   ++__to_incr;
+   __incr();
  }
  }
  }
@@ -323,21 +324,19 @@ namespace __unicode
 
if (__u < __lo_bound_2 || __u > __hi_bound_2) [[unlikely]]
  __c = _S_error();
-   else if (++_M_curr() == _M_last) [[unlikely]]
+   else if (__incr() == _M_last) [[unlikely]]
  __c = _S_error();
else
  {
-   ++__to_incr;
__c = (__c << 6) | (__u & 0x3F);
__u = *_M_curr();
 
if (__u < __lo_bound || __u > __hi_bound) [[unlikely]]
  __c = _S_error();
-   else if (++_M_curr() == _M_last) [[unlikely]]
+   else if (__incr() == _M_last) [[unlikely]]
  __c = _S_error();
else
  {
-   ++__to_incr;
__c = (__c << 6) | (__u & 0x3F);
__u = *_M_curr();
 
@@ -346,8 +345,7 @@ namespace __unicode
else
  {
__c = (__c << 6) | (__u & 0x3F);
-   ++_M_curr();
-   ++__to_incr;
+   __incr();
  }
  }
  }
diff --git a/libstdc++-v3/testsuite/ext/unicode/view.cc 
b/libstdc++-v3/testsuite/ext/unicode/view.cc
index ee23b0b1d8a3..6f3c099bd84a 100644
--- a/libstdc++-v3/testsuite/ext/unicode/view.cc
+++ b/libstdc++-v3/testsuite/ext/unicode/view.cc
@@ -55,6 +55,13 @@ test_illformed_utf8()
   VERIFY( std::ranges::equal(v5, 
u8"\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\x41\uFFFD\uFFFD\x42"sv) );
   uc::_Utf8_view v6("\xe1\x80

[gcc r14-10205] libstdc++: Update ABI test to disallow adding to released symbol versions

2024-05-14 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:788ccd269e0c32c33ce0c1359137fe1b35dc7a2d

commit r14-10205-g788ccd269e0c32c33ce0c1359137fe1b35dc7a2d
Author: Jonathan Wakely 
Date:   Thu Apr 11 15:35:11 2024 +0100

libstdc++: Update ABI test to disallow adding to released symbol versions

If we update the list of "active" symbols versions now, rather than when
adding a new symbol version, we will notice if new symbols get added to
the wrong version (as in PR 114692).

libstdc++-v3/ChangeLog:

* testsuite/util/testsuite_abi.cc: Update latest versions to
new versions that should be used in future.

(cherry picked from commit 6e25ca387fbbb412a2e498e28ea5db28e033a318)

Diff:
---
 libstdc++-v3/testsuite/util/testsuite_abi.cc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/testsuite/util/testsuite_abi.cc 
b/libstdc++-v3/testsuite/util/testsuite_abi.cc
index e4bf3cdc8e07..ec7c3df9eccb 100644
--- a/libstdc++-v3/testsuite/util/testsuite_abi.cc
+++ b/libstdc++-v3/testsuite/util/testsuite_abi.cc
@@ -254,8 +254,8 @@ check_version(symbol& test, bool added)
test.version_status = symbol::incompatible;
 
   // Check that added symbols are added in the latest pre-release version.
-  bool latestp = (test.version_name == "GLIBCXX_3.4.33"
-|| test.version_name == "CXXABI_1.3.15"
+  bool latestp = (test.version_name == "GLIBCXX_3.4.34"
+|| test.version_name == "CXXABI_1.3.16"
 || test.version_name == "CXXABI_FLOAT128"
 || test.version_name == "CXXABI_TM_1");
   if (added && !latestp)


[gcc r14-10203] libstdc++: Fix for -std=c++23 -ffreestanding [PR114866]

2024-05-14 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:95055199ee80e526da98c3458308fa345a041d9a

commit r14-10203-g95055199ee80e526da98c3458308fa345a041d9a
Author: Jonathan Wakely 
Date:   Thu May 2 12:14:52 2024 +0100

libstdc++: Fix  for -std=c++23 -ffreestanding [PR114866]

std::shared_ptr isn't declared for freestanding, so guard uses of it
with #if _GLIBCXX_HOSTED in .

libstdc++-v3/ChangeLog:

PR libstdc++/114866
* include/bits/out_ptr.h [!_GLIBCXX_HOSTED]: Don't refer to
shared_ptr, __shared_ptr or __is_shred_ptr.
* testsuite/20_util/headers/memory/114866.cc: New test.

(cherry picked from commit 9927059bb88e966e0a45f09e4fd1193f93df708f)

Diff:
---
 libstdc++-v3/include/bits/out_ptr.h | 10 ++
 libstdc++-v3/testsuite/20_util/headers/memory/114866.cc |  4 
 2 files changed, 14 insertions(+)

diff --git a/libstdc++-v3/include/bits/out_ptr.h 
b/libstdc++-v3/include/bits/out_ptr.h
index aeeb66404418..d74c9f52d3b5 100644
--- a/libstdc++-v3/include/bits/out_ptr.h
+++ b/libstdc++-v3/include/bits/out_ptr.h
@@ -54,9 +54,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 class out_ptr_t
 {
+#if _GLIBCXX_HOSTED
   static_assert(!__is_shared_ptr<_Smart> || sizeof...(_Args) != 0,
"a deleter must be used when adapting std::shared_ptr "
"with std::out_ptr");
+#endif
 
 public:
   explicit
@@ -216,6 +218,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  [[no_unique_address]] _Del2 _M_del;
};
 
+#if _GLIBCXX_HOSTED
   // Partial specialization for std::shared_ptr.
   // This specialization gives direct access to the private member
   // of the shared_ptr, avoiding the overhead of storing a separate
@@ -274,6 +277,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
  using _Impl<_Smart, _Pointer, _Del, allocator>::_Impl;
};
+#endif
 
   using _Impl_t = _Impl<_Smart, _Pointer, _Args...>;
 
@@ -293,8 +297,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 class inout_ptr_t
 {
+#if _GLIBCXX_HOSTED
   static_assert(!__is_shared_ptr<_Smart>,
"std::inout_ptr can not be used to wrap std::shared_ptr");
+#endif
 
 public:
   explicit
@@ -320,11 +326,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   }
 
 private:
+#if _GLIBCXX_HOSTED
   // Avoid an invalid instantiation of out_ptr_t, ...>
   using _Out_ptr_t
= __conditional_t<__is_shared_ptr<_Smart>,
  out_ptr_t,
  out_ptr_t<_Smart, _Pointer, _Args...>>;
+#else
+  using _Out_ptr_t = out_ptr_t<_Smart, _Pointer, _Args...>;
+#endif
   using _Impl_t = typename _Out_ptr_t::_Impl_t;
   _Impl_t _M_impl;
 };
diff --git a/libstdc++-v3/testsuite/20_util/headers/memory/114866.cc 
b/libstdc++-v3/testsuite/20_util/headers/memory/114866.cc
new file mode 100644
index ..7cf6be0539d2
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/headers/memory/114866.cc
@@ -0,0 +1,4 @@
+// { dg-options "-ffreestanding" }
+// { dg-do compile }
+// PR libstdc++/114866  & out_ptr in freestanding
+#include 


Re: [PATCH] libstdc++: Use __builtin_shufflevector for simd split and concat

2024-05-13 Thread Jonathan Wakely
On Tue, 7 May 2024 at 14:42, Matthias Kretz  wrote:
>
> Tested on x86_64-linux-gnu and aarch64-linux-gnu and with Clang 18 on x86_64-
> linux-gnu.
>
> OK for trunk and backport(s)?

OK for all.


>
> -- 8< 
>
> Signed-off-by: Matthias Kretz 
>
> libstdc++-v3/ChangeLog:
>
> PR libstdc++/114958
> * include/experimental/bits/simd.h (__as_vector): Return scalar
> simd as one-element vector. Return vector from single-vector
> fixed_size simd.
> (__vec_shuffle): New.
> (__extract_part): Adjust return type signature.
> (split): Use __extract_part for any split into non-fixed_size
> simds.
> (concat): If the return type stores a single vector, use
> __vec_shuffle (which calls __builtin_shufflevector) to produce
> the return value.
> * include/experimental/bits/simd_builtin.h
> (__shift_elements_right): Removed.
> (__extract_part): Return single elements directly. Use
> __vec_shuffle (which calls __builtin_shufflevector) to for all
> non-trivial cases.
> * include/experimental/bits/simd_fixed_size.h (__extract_part):
> Return single elements directly.
> * testsuite/experimental/simd/pr114958.cc: New test.
> ---
>  libstdc++-v3/include/experimental/bits/simd.h | 161 +-
>  .../include/experimental/bits/simd_builtin.h  | 152 +
>  .../experimental/bits/simd_fixed_size.h   |   4 +-
>  .../testsuite/experimental/simd/pr114958.cc   |  20 +++
>  4 files changed, 145 insertions(+), 192 deletions(-)
>  create mode 100644 libstdc++-v3/testsuite/experimental/simd/pr114958.cc
>
>
> --
> ──
>  Dr. Matthias Kretz   https://mattkretz.github.io
>  GSI Helmholtz Centre for Heavy Ion Research   https://gsi.de
>  stdₓ::simd
> ──



Re: Fix gnu versioned namespace mode 00/03

2024-05-13 Thread Jonathan Wakely
On Mon, 13 May 2024, 07:30 Iain Sandoe,  wrote:

>
>
> > On 13 May 2024, at 06:06, François Dumont  wrote:
> >
> >
> > On 07/05/2024 18:15, Iain Sandoe wrote:
> >> Hi François
> >>
> >>> On 4 May 2024, at 22:11, François Dumont  wrote:
> >>>
> >>> Here is the list of patches to restore gnu versioned namespace mode.
> >>>
> >>> 1/3: Bump gnu version namespace
> >>>
> >>> This is important to be done first so that once build of gnu versioned
> namespace is fixed there is no chance to have another build of '__8'
> version with a different abi than last successful '__8' build.
>


The versioned namespace build is not expected to be ABI compatible though,
so nobody should be expecting compatibility with previous builds.
Especially not on the gcc-15 trunk, a week or two after entering stage 1!


> >>>
> >>> 2/3: Fix build using cxx11 abi for versioned namespace
> >>>
> >>> 3/3: Proposal to default to "new" abi when dual abi is disabled and
> accept any default-libstdcxx-abi either dual abi is enabled or not.
> >>>
> >>> All testsuite run for following configs:
> >>>
> >>> - dual abi
> >>>
> >>> - gcc4-compatible only abi
> >>>
> >>> - new only abi
> >>>
> >>> - versioned namespace abi
> >> At the risk of delaying this (a bit) - I think we should also consider
> items like once_call that have broken impls.
> > Do you have any pointer to this once_call problem, sorry I'm not aware
> about it (apart from your messages).
>
> (although this mentions one specific target, it applies more widely).
>

I've removed the "on ppc64le" part from the summary.

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66146
>
> Also, AFAICT, any nested once_call is a problem (not just exceptions).
>

Could you update the bug with that info please?


> >>  in the current library - and at least get proposed replacements
> available behind the versioned namespace; rather than using up a namespace
> version with the current broken code.
> >
> > I'm not proposing to fix all library bugs on all platforms with this
> patch, just fix the versioned namespace mode.
>
> Sorry, I was not intending to suggest that (although perhaps my comments
> read that way).
>
> I was trying to suggest that, in the case where we have proposed fixes
> that are blocked because they are ABI breaks, that those could be put
> behind the versioned namspace (it was not an intention to suggest that such
> additions should be part of this patch series).
>
> > As to do so I also need to adopt cxx11 abi in versioned mode it already
> justify a bump of version.
>
> I see - it’s just a bit strange that we are bumping a version for a mode
> that does not currently work;  however, i guess someone might have deployed
> it even so.
>

It does work though, doesn't it?
It's known to fail on powerpc64 due to conflicts with the ieee128 stuff,
but it should work elsewhere.
It doesn't work with --with-default-libstdcxx-abi=cxx11 but that's just a
"this doesn't work and isn't supported" limitation.

The point of the patch series is to change it so the versioned namespace
always uses the cxx11 ABI, which does seem worth bumping the version (even
though the versioned namespace is explicitly not a stable ABI and not
backwards compatible).


>
> > The reason I'm proposing to integrate this patch this early in gcc 15
> stage is to have time to integrate any other library fix/optimization that
> could make use of it. I already have 1 on my side for the hashtable
> implementation
>
> Ah, then I think we are aiming for the same thing.
>
> > . I hope your once_call fix also have time to be ready for gcc 15, no ?
>
> Yes; if we put it behind the versioned namespace - there are (I think)
> several proposed solutions to that specific issue.
>
> thanks
> Iain
>
> >
> > François
>
>


Re: [PATCH][risc-v] libstdc++: Preserve signbit of nan when converting float to double [PR113578]

2024-05-10 Thread Jonathan Wakely
On Tue, 7 May 2024 at 15:11, Jonathan Wakely  wrote:
>
> On Tue, 7 May 2024 at 15:06, Jonathan Wakely wrote:
> >
> > On Tue, 7 May 2024 at 14:57, Jeff Law wrote:
> > >
> > >
> > >
> > > On 5/7/24 7:49 AM, Jonathan Wakely wrote:
> > > > Do we want this change for RISC-V, to fix PR113578?
> > > >
> > > > I haven't tested it on RISC-V, only on x86_64-linux (where it doesn't do
> > > > anything).
> > > >
> > > > -- >8 --
> > > >
> > > > libstdc++-v3/ChangeLog:
> > > >
> > > >   PR libstdc++/113578
> > > >   * include/std/ostream (operator<<(basic_ostream&, float)):
> > > >   Restore signbit after converting to double.
> > > No strong opinion. One could argue that the existence of a
> > > conditional like that inherently implies the generic code is dependent
> > > on specific processor behavior which probably is unwise.  But again, no
> > > strong opinion.
> >
> > Yes, but I'm not aware of any other processors that lose the signbit
> > like this, so in practice it's always worked fine to cast the float to
> > double.
>
> The similar glibc fix for strfrom is specific to RISC-V:
> https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=0cc0033ef19bd3378445c2b851e53d7255cb1b1e

Looks like I spoke too soon and the same behaviour exists on Apple M1 chips.


>
> My patch uses copysign unconditionally, to avoid branching on isnan. I
> don't know if that's the right choice.



Re: [PATCH][risc-v] libstdc++: Preserve signbit of nan when converting float to double [PR113578]

2024-05-08 Thread Jonathan Wakely
On Wed, 8 May 2024 at 11:33, Andrew Waterman  wrote:
>
> On Tue, May 7, 2024 at 9:46 AM Jonathan Wakely  wrote:
> >
> > On Tue, 7 May 2024 at 17:39, Jonathan Wakely  wrote:
> > >
> > > On Tue, 7 May 2024 at 17:33, Jeff Law wrote:
> > > >
> > > >
> > > >
> > > > On 5/7/24 9:36 AM, Andreas Schwab wrote:
> > > > > On Mai 07 2024, Jonathan Wakely wrote:
> > > > >
> > > > >> +#ifdef __riscv
> > > > >> +return _M_insert(__builtin_copysign((double)__f,
> > > > >> +
> > > > >> (double)-__builtin_signbit(__f));
> > > > >
> > > > > Should this use static_cast?
> > >
> > > Meh. It wouldn't fit in 80 columns any more with static_cast, and it
> > > means exactly the same thing.
> > >
> > > > And it's missing a close paren.
> > >
> > > Now that's more important! Thanks.
> >
> > Also, I've just realised that signbit might return a negative value if
> > the signbit is set. The spec only says it returns non-zero if the
> > signbit is set.
> >
> > So maybe we want:
> >
> > #ifdef __riscv
> > const int __neg = __builtin_signbit(__f) ? -1 : 0;
> > return _M_insert(__builtin_copysign(static_cast(__f),
> >   static_cast(__neg)));
> > #else
> > return _M_insert(static_cast(__f));
> > #endif
>
> We can avoid the signbit call altogether by taking advantage of the
> fact that type-punning the float to an int, then converting that int
> to a double, will produce a double with the sign of the original
> value, with no exceptions raised in the process.  (I don't know
> whether we're allowed to use std::bit_cast in this context, but a
> type-punning memcpy would have the same effect.)

I'll check when Clang added support for __builtin_bit_cast, but I
think we can use that (we can't use std::bit_cast because this needs
to compile as C++98).


>
>   int __i = std::bit_cast(__f);
>   return _M_insert(__builtin_copysign(static_cast(__f),
> static_cast(__i)));
>
> Empirically, this saves 3 instructions on RV64 or 1 instruction on
> RV32 (as measured on GCC 13.2.0).  Note, I'm not trying to drag-race
> on performance here.  Rather, I'm trying to minimize the extent to
> which this RISC-V idiosyncrasy results in static code-size bloat.

Yup, this is nice, thanks.

>
> BTW, I agree with Palmer that adding a __builtin with these semantics
> seems advisable if this pattern turns out to recur frequently.
>



Re: [PATCH][risc-v] libstdc++: Preserve signbit of nan when converting float to double [PR113578]

2024-05-07 Thread Jonathan Wakely
On Tue, 7 May 2024 at 17:39, Jonathan Wakely  wrote:
>
> On Tue, 7 May 2024 at 17:33, Jeff Law wrote:
> >
> >
> >
> > On 5/7/24 9:36 AM, Andreas Schwab wrote:
> > > On Mai 07 2024, Jonathan Wakely wrote:
> > >
> > >> +#ifdef __riscv
> > >> +return _M_insert(__builtin_copysign((double)__f,
> > >> +
> > >> (double)-__builtin_signbit(__f));
> > >
> > > Should this use static_cast?
>
> Meh. It wouldn't fit in 80 columns any more with static_cast, and it
> means exactly the same thing.
>
> > And it's missing a close paren.
>
> Now that's more important! Thanks.

Also, I've just realised that signbit might return a negative value if
the signbit is set. The spec only says it returns non-zero if the
signbit is set.

So maybe we want:

#ifdef __riscv
const int __neg = __builtin_signbit(__f) ? -1 : 0;
return _M_insert(__builtin_copysign(static_cast(__f),
  static_cast(__neg)));
#else
return _M_insert(static_cast(__f));
#endif


Re: [PATCH][risc-v] libstdc++: Preserve signbit of nan when converting float to double [PR113578]

2024-05-07 Thread Jonathan Wakely
On Tue, 7 May 2024 at 17:33, Jeff Law wrote:
>
>
>
> On 5/7/24 9:36 AM, Andreas Schwab wrote:
> > On Mai 07 2024, Jonathan Wakely wrote:
> >
> >> +#ifdef __riscv
> >> +return _M_insert(__builtin_copysign((double)__f,
> >> +(double)-__builtin_signbit(__f));
> >
> > Should this use static_cast?

Meh. It wouldn't fit in 80 columns any more with static_cast, and it
means exactly the same thing.

> And it's missing a close paren.

Now that's more important! Thanks.


Re: [PATCH][risc-v] libstdc++: Preserve signbit of nan when converting float to double [PR113578]

2024-05-07 Thread Jonathan Wakely
On Tue, 7 May 2024 at 15:06, Jonathan Wakely wrote:
>
> On Tue, 7 May 2024 at 14:57, Jeff Law wrote:
> >
> >
> >
> > On 5/7/24 7:49 AM, Jonathan Wakely wrote:
> > > Do we want this change for RISC-V, to fix PR113578?
> > >
> > > I haven't tested it on RISC-V, only on x86_64-linux (where it doesn't do
> > > anything).
> > >
> > > -- >8 --
> > >
> > > libstdc++-v3/ChangeLog:
> > >
> > >   PR libstdc++/113578
> > >   * include/std/ostream (operator<<(basic_ostream&, float)):
> > >   Restore signbit after converting to double.
> > No strong opinion. One could argue that the existence of a
> > conditional like that inherently implies the generic code is dependent
> > on specific processor behavior which probably is unwise.  But again, no
> > strong opinion.
>
> Yes, but I'm not aware of any other processors that lose the signbit
> like this, so in practice it's always worked fine to cast the float to
> double.

The similar glibc fix for strfrom is specific to RISC-V:
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=0cc0033ef19bd3378445c2b851e53d7255cb1b1e

My patch uses copysign unconditionally, to avoid branching on isnan. I
don't know if that's the right choice.



Re: [PATCH][risc-v] libstdc++: Preserve signbit of nan when converting float to double [PR113578]

2024-05-07 Thread Jonathan Wakely
On Tue, 7 May 2024 at 14:57, Jeff Law wrote:
>
>
>
> On 5/7/24 7:49 AM, Jonathan Wakely wrote:
> > Do we want this change for RISC-V, to fix PR113578?
> >
> > I haven't tested it on RISC-V, only on x86_64-linux (where it doesn't do
> > anything).
> >
> > -- >8 --
> >
> > libstdc++-v3/ChangeLog:
> >
> >   PR libstdc++/113578
> >   * include/std/ostream (operator<<(basic_ostream&, float)):
> >   Restore signbit after converting to double.
> No strong opinion. One could argue that the existence of a
> conditional like that inherently implies the generic code is dependent
> on specific processor behavior which probably is unwise.  But again, no
> strong opinion.

Yes, but I'm not aware of any other processors that lose the signbit
like this, so in practice it's always worked fine to cast the float to
double.



[PATCH 2/2] libstdc++: Fix data races in std::ctype [PR77704]

2024-05-07 Thread Jonathan Wakely
Tested x86_64-linux. This one is less "obviously correct", as calling
the single-character narrow(char, char) overload no longer lazily
populates individual characters in the cache (because doing that is
racy). And the single-character widen(char) no longer calls
_M_wide_init() to populate the whole widening cache.

The current code definitely has a data race, i.e. undefined behaviour,
so we need to do _something_. But maybe not this. Maybe it would be
better to keep calling _M_widen_init() from widen(char), so that
iostream construction will fill the cache on the first call to the
global locale's widen(' '), and then be faster after that (which is the
current behaviour). Maybe we want to add that to narrow(char, char) too
(which is not the current behaviour).

I raised the question on the LWG list of whether it's OK for calls to
ctype::narrow(char, char) to result in calls to the virtual function
ctype::do_narrow(const char*, const char*, char, char*), and for calls
to ctype::narrow(const char*, const char*, char, char*) to result in
calls to the virtual function ctype::do_narrow(char, char). If that
isn't OK then our entire caching scheme in std::ctype is not
allowed, and we'd need to ensure each call to narrow results in exactly
one call to the corresponding do_narrow, and nothing else.

-- >8 --

The std::ctype specialization uses mutable data members to cache
the results of do_narrow calls, to avoid virtual calls.  However, the
accesses to those mutable members are not synchronized and so there are
data races when using the facet in multiple threads.

This change ensures that the _M_narrow_ok status flag is only accessed
atomically, avoiding any races on that member.

The _M_narrow_init() member function is changed to use a mutex (with
double-checked locking), so that writing to the _M_narrow array only
happens in one thread. The function is rearranged so that the virtual
calls and comparing the arrays are done outside the critical section,
then all writes to member variables are done last, inside the critical
section.  Importantly, the _M_narrow_ok member is not set until after
the _M_narrow array has been populated.

The narrow(char, char) function will now only read from _M_narrow if
_M_narrow_ok is non-zero. This means that populating the array
happens-before reading from it. If the cache isn't available and a
virtual call to do_narrow(c, d) is needed, this function no longer
stores the result in the cache, because only _M_narrow_init() can write
to the cache now. This means that repeated calls to narrow(c, d) with
the same value of c will no longer avoid calling do_narrow(c, d). If
this impacts performance too significantly then we could make
narrow(char, char) call _M_narrow_init() to populate the cache, or just
call _M_narrow_init() on construction so the cache is always available.
In the current code widen(wchar_t) always calls _M_widen_init() to
populate that cache, but I've removed that call to be consistent with
narrow(char, char) which doesn't initialize the narrow cache. This will
impact std::basic_ios::init (used when constructing any iostream
object) which calls widen(' ') on the global locale's std::ctype
facet, so maybe we do want to warm up that cache still.

The narrow(const char*, const char*, char. char*) overload now re-checks
the _M_narrow_ok status flag after calling _M_narrow_init(), so that we
don't make an unnecessary virtual call if _M_narrow_init() set the
status flag to 1, meaning the base class version of do_narrow (using
memcpy) can be used. Reloading the status flag after calling
_M_narrow_init() can be a relaxed load, because _M_narrow_init() either
did a load with acquire ordering, or set the flag itself in the current
thread.

Similar changes are needed for the std::ctype::widen members,
which are also defined in terms of mutable data members without
synchronization.

The 22_locale/ctype/narrow/char/19955.cc test needs to be fixed to work
with the new code, because it currently assumes that the library will
only use the array form of do_narrow, and the Ctype1::do_narrow override
is not idempotent.

libstdc++-v3/ChangeLog:

PR libstdc++/77704
* include/bits/locale_facets.h (ctype::widen(char)): Check
if cache is initialized before using it.
(ctype::narrow(char, char)): Likewise.
(ctype::widen(const char*, const char*, char, char*)):
Check again if memcpy can be used after initializing the cache.
(ctype::narrow(const char*, const char*, char, char*)):
Likewise.
(ctype::_M_narrow_cache_status(int)): New member function.
(ctype::_M_widen_cache_status(int)): New member function.
* src/c++11/ctype.cc (ctype::_M_narrow_init) [__GTHREADS]:
Use atomics and a mutex to synchronize accesses to _M_narrow_ok
and _M_narrow.
(ctype::_M_widen_init) [__GTHREADS]: Likewise.
* testsuite/22_locale/ctype/narrow/char/19955.cc: Fix test
facets so that the array 

[PATCH 1/2] libstdc++: Fix data race in std::basic_ios::fill() [PR77704]

2024-05-07 Thread Jonathan Wakely
Tested x86_64-linux. This seems "obviously correct", and I'd like to
push it. The current code definitely has a data race, i.e. undefined
behaviour.

-- >8 --

The lazy caching in std::basic_ios::fill() updates a mutable member
without synchronization, which can cause a data race if two threads both
call fill() on the same stream object when _M_fill_init is false.

To avoid this we can just cache the _M_fill member and set _M_fill_init
early in std::basic_ios::init, instead of doing it lazily. As explained
by the comment in init, there's a good reason for doing it lazily. When
char_type is neither char nor wchar_t, the locale might not have a
std::ctype, so getting the fill character would throw an
exception. The current lazy init allows using unformatted I/O with such
a stream, because the fill character is never needed and so it doesn't
matter if the locale doesn't have a ctype facet. We can
maintain this property by only setting the fill character in
std::basic_ios::init if the ctype facet is present at that time. If
fill() is called later and the fill character wasn't set by init, we can
get it from the stream's current locale at the point when fill() is
called (and not try to cache it without synchronization).

This causes a change in behaviour for the following program:

  std::ostringstream out;
  out.imbue(loc);
  auto fill = out.fill();

Previously the fill character would have been set when fill() is called,
and so would have used the new locale. This commit changes it so that
the fill character is set on construction and isn't affected by the new
locale being imbued later. This new behaviour seems to be what the
standard requires, and matches MSVC.

The new 27_io/basic_ios/fill/char/fill.cc test verifies that it's still
possible to use a std::basic_ios without the ctype facet
being present at construction.

libstdc++-v3/ChangeLog:

PR libstdc++/77704
* include/bits/basic_ios.h (basic_ios::fill()): Do not modify
_M_fill and _M_fill_init in a const member function.
(basic_ios::fill(char_type)): Use _M_fill directly instead of
calling fill(). Set _M_fill_init to true.
* include/bits/basic_ios.tcc (basic_ios::init): Set _M_fill and
_M_fill_init here instead.
* testsuite/27_io/basic_ios/fill/char/1.cc: New test.
* testsuite/27_io/basic_ios/fill/wchar_t/1.cc: New test.
---
 libstdc++-v3/include/bits/basic_ios.h | 10 +--
 libstdc++-v3/include/bits/basic_ios.tcc   | 15 +++-
 .../testsuite/27_io/basic_ios/fill/char/1.cc  | 78 +++
 .../27_io/basic_ios/fill/wchar_t/1.cc | 55 +
 4 files changed, 148 insertions(+), 10 deletions(-)
 create mode 100644 libstdc++-v3/testsuite/27_io/basic_ios/fill/char/1.cc
 create mode 100644 libstdc++-v3/testsuite/27_io/basic_ios/fill/wchar_t/1.cc

diff --git a/libstdc++-v3/include/bits/basic_ios.h 
b/libstdc++-v3/include/bits/basic_ios.h
index 258e6042b8f..bc3be4d2e37 100644
--- a/libstdc++-v3/include/bits/basic_ios.h
+++ b/libstdc++-v3/include/bits/basic_ios.h
@@ -373,11 +373,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   char_type
   fill() const
   {
-   if (!_M_fill_init)
- {
-   _M_fill = this->widen(' ');
-   _M_fill_init = true;
- }
+   if (__builtin_expect(!_M_fill_init, false))
+ return this->widen(' ');
return _M_fill;
   }
 
@@ -393,8 +390,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   char_type
   fill(char_type __ch)
   {
-   char_type __old = this->fill();
+   char_type __old = _M_fill;
_M_fill = __ch;
+   _M_fill_init = true;
return __old;
   }
 
diff --git a/libstdc++-v3/include/bits/basic_ios.tcc 
b/libstdc++-v3/include/bits/basic_ios.tcc
index a9313736e32..0197bdf8f67 100644
--- a/libstdc++-v3/include/bits/basic_ios.tcc
+++ b/libstdc++-v3/include/bits/basic_ios.tcc
@@ -138,13 +138,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // return without throwing an exception. Unfortunately,
   // ctype is not necessarily a required facet, so
   // streams with char_type != [char, wchar_t] will not have it by
-  // default. Because of this, the correct value for _M_fill is
-  // constructed on the first call of fill(). That way,
+  // default. If the ctype facet is available now,
+  // _M_fill is set here, but otherwise no fill character will be
+  // cached and a call to fill() will check for the facet again later
+  // (and will throw if the facet is still not present). This way
   // unformatted input and output with non-required basic_ios
   // instantiations is possible even without imbuing the expected
   // ctype facet.
-  _M_fill = _CharT();
-  _M_fill_init = false;
+  if (_M_ctype)
+   {
+ _M_fill = _M_ctype->widen(' ');
+ _M_fill_init = true;
+   }
+  else
+   _M_fill_init = false;
 
   _M_tie = 0;
   _M_exception = goodbit;
diff --git 

[PATCH][risc-v] libstdc++: Preserve signbit of nan when converting float to double [PR113578]

2024-05-07 Thread Jonathan Wakely
Do we want this change for RISC-V, to fix PR113578?

I haven't tested it on RISC-V, only on x86_64-linux (where it doesn't do
anything).

-- >8 --

libstdc++-v3/ChangeLog:

PR libstdc++/113578
* include/std/ostream (operator<<(basic_ostream&, float)):
Restore signbit after converting to double.
---
 libstdc++-v3/include/std/ostream | 5 +
 1 file changed, 5 insertions(+)

diff --git a/libstdc++-v3/include/std/ostream b/libstdc++-v3/include/std/ostream
index 8a21758d0a3..d492168ca0e 100644
--- a/libstdc++-v3/include/std/ostream
+++ b/libstdc++-v3/include/std/ostream
@@ -233,7 +233,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   {
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 117. basic_ostream uses nonexistent num_put member functions.
+#ifdef __riscv
+   return _M_insert(__builtin_copysign((double)__f,
+   (double)-__builtin_signbit(__f));
+#else
return _M_insert(static_cast(__f));
+#endif
   }
 
   __ostream_type&
-- 
2.44.0



[committed] libstdc++: Fix handling of incomplete UTF-8 sequences in _Unicode_view

2024-05-07 Thread Jonathan Wakely
Tested x86_64-linux. Pushed to trunk. gcc-14 backport to follow.

-- >8 --

Eddie Nolan reported to me that _Unicode_view was not correctly
implementing the substitution of ill-formed subsequences with U+FFFD,
due to failing to increment the counter when the iterator reaches the
end of the sequence before a multibyte sequence is complete.  As a
result, the incomplete sequence was not completely consumed, and then
the remaining character was treated as another ill-formed sequence,
giving two U+FFFD characters instead of one.

To avoid similar mistakes in future, this change introduces a lambda
that increments the iterator and the counter together. This ensures the
counter is always incremented when the iterator is incremented, so that
we always know how many characters have been consumed.

libstdc++-v3/ChangeLog:

* include/bits/unicode.h (_Unicode_view::_M_read_utf8): Ensure
count of characters consumed is correct when the end of the
input is reached unexpectedly.
* testsuite/ext/unicode/view.cc: Test incomplete UTF-8
sequences.
---
 libstdc++-v3/include/bits/unicode.h| 24 ++
 libstdc++-v3/testsuite/ext/unicode/view.cc |  7 +++
 2 files changed, 18 insertions(+), 13 deletions(-)

diff --git a/libstdc++-v3/include/bits/unicode.h 
b/libstdc++-v3/include/bits/unicode.h
index 29813b743dc..46238143fb6 100644
--- a/libstdc++-v3/include/bits/unicode.h
+++ b/libstdc++-v3/include/bits/unicode.h
@@ -261,9 +261,13 @@ namespace __unicode
   {
_Guard<_Iter> __g{this, _M_curr()};
char32_t __c{};
-   uint8_t __u = *_M_curr()++;
const uint8_t __lo_bound = 0x80, __hi_bound = 0xBF;
+   uint8_t __u = *_M_curr()++;
uint8_t __to_incr = 1;
+   auto __incr = [&, this] {
+ ++__to_incr;
+ return ++_M_curr();
+   };
 
if (__u <= 0x7F) [[likely]]  // 0x00 to 0x7F
  __c = __u;
@@ -281,8 +285,7 @@ namespace __unicode
else
  {
__c = (__c << 6) | (__u & 0x3F);
-   ++_M_curr();
-   ++__to_incr;
+   __incr();
  }
  }
else if (__u <= 0xEF) // 0xE0 to 0xEF
@@ -295,11 +298,10 @@ namespace __unicode
 
if (__u < __lo_bound_2 || __u > __hi_bound_2) [[unlikely]]
  __c = _S_error();
-   else if (++_M_curr() == _M_last) [[unlikely]]
+   else if (__incr() == _M_last) [[unlikely]]
  __c = _S_error();
else
  {
-   ++__to_incr;
__c = (__c << 6) | (__u & 0x3F);
__u = *_M_curr();
 
@@ -308,8 +310,7 @@ namespace __unicode
else
  {
__c = (__c << 6) | (__u & 0x3F);
-   ++_M_curr();
-   ++__to_incr;
+   __incr();
  }
  }
  }
@@ -323,21 +324,19 @@ namespace __unicode
 
if (__u < __lo_bound_2 || __u > __hi_bound_2) [[unlikely]]
  __c = _S_error();
-   else if (++_M_curr() == _M_last) [[unlikely]]
+   else if (__incr() == _M_last) [[unlikely]]
  __c = _S_error();
else
  {
-   ++__to_incr;
__c = (__c << 6) | (__u & 0x3F);
__u = *_M_curr();
 
if (__u < __lo_bound || __u > __hi_bound) [[unlikely]]
  __c = _S_error();
-   else if (++_M_curr() == _M_last) [[unlikely]]
+   else if (__incr() == _M_last) [[unlikely]]
  __c = _S_error();
else
  {
-   ++__to_incr;
__c = (__c << 6) | (__u & 0x3F);
__u = *_M_curr();
 
@@ -346,8 +345,7 @@ namespace __unicode
else
  {
__c = (__c << 6) | (__u & 0x3F);
-   ++_M_curr();
-   ++__to_incr;
+   __incr();
  }
  }
  }
diff --git a/libstdc++-v3/testsuite/ext/unicode/view.cc 
b/libstdc++-v3/testsuite/ext/unicode/view.cc
index ee23b0b1d8a..6f3c099bd84 100644
--- a/libstdc++-v3/testsuite/ext/unicode/view.cc
+++ b/libstdc++-v3/testsuite/ext/unicode/view.cc
@@ -55,6 +55,13 @@ test_illformed_utf8()
   VERIFY( std::ranges::equal(v5, 
u8"\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\x41\uFFFD\uFFFD\x42"sv) );
   uc::_Utf8_view v6("\xe1\x80\xe2\xf0\x91\x92\xf1\xbf\x41"sv); // Table 3-11
   VERIFY( std::ranges::equal(v6, u8"\uFFFD\uFFFD\uFFFD\uFFFD\x41"sv) );
+
+  uc::_Utf32_view v7("\xe1\x80"sv);
+  VERIFY( std::ranges::equal(v7, U"\uFFFD"sv) );
+  uc::_Utf32_view v8("\xf1\x80"sv);
+  VERIFY( std::ranges::equal(v8, U"\uFFFD"sv) );
+  uc::_Utf32_view v9("\xf1\x80\x80"sv);
+  VERIFY( std::ranges::equal(v9, U"\uFFFD"sv) );
 }
 
 constexpr void
-- 
2.44.0



[gcc r15-285] libstdc++: Fix handling of incomplete UTF-8 sequences in _Unicode_view

2024-05-07 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:3f04f3939ea0ac8fdd766a60655d29de2ffb44e5

commit r15-285-g3f04f3939ea0ac8fdd766a60655d29de2ffb44e5
Author: Jonathan Wakely 
Date:   Wed May 1 17:09:39 2024 +0100

libstdc++: Fix handling of incomplete UTF-8 sequences in _Unicode_view

Eddie Nolan reported to me that _Unicode_view was not correctly
implementing the substitution of ill-formed subsequences with U+FFFD,
due to failing to increment the counter when the iterator reaches the
end of the sequence before a multibyte sequence is complete.  As a
result, the incomplete sequence was not completely consumed, and then
the remaining character was treated as another ill-formed sequence,
giving two U+FFFD characters instead of one.

To avoid similar mistakes in future, this change introduces a lambda
that increments the iterator and the counter together. This ensures the
counter is always incremented when the iterator is incremented, so that
we always know how many characters have been consumed.

libstdc++-v3/ChangeLog:

* include/bits/unicode.h (_Unicode_view::_M_read_utf8): Ensure
count of characters consumed is correct when the end of the
input is reached unexpectedly.
* testsuite/ext/unicode/view.cc: Test incomplete UTF-8
sequences.

Diff:
---
 libstdc++-v3/include/bits/unicode.h| 24 +++-
 libstdc++-v3/testsuite/ext/unicode/view.cc |  7 +++
 2 files changed, 18 insertions(+), 13 deletions(-)

diff --git a/libstdc++-v3/include/bits/unicode.h 
b/libstdc++-v3/include/bits/unicode.h
index 29813b743dc..46238143fb6 100644
--- a/libstdc++-v3/include/bits/unicode.h
+++ b/libstdc++-v3/include/bits/unicode.h
@@ -261,9 +261,13 @@ namespace __unicode
   {
_Guard<_Iter> __g{this, _M_curr()};
char32_t __c{};
-   uint8_t __u = *_M_curr()++;
const uint8_t __lo_bound = 0x80, __hi_bound = 0xBF;
+   uint8_t __u = *_M_curr()++;
uint8_t __to_incr = 1;
+   auto __incr = [&, this] {
+ ++__to_incr;
+ return ++_M_curr();
+   };
 
if (__u <= 0x7F) [[likely]]  // 0x00 to 0x7F
  __c = __u;
@@ -281,8 +285,7 @@ namespace __unicode
else
  {
__c = (__c << 6) | (__u & 0x3F);
-   ++_M_curr();
-   ++__to_incr;
+   __incr();
  }
  }
else if (__u <= 0xEF) // 0xE0 to 0xEF
@@ -295,11 +298,10 @@ namespace __unicode
 
if (__u < __lo_bound_2 || __u > __hi_bound_2) [[unlikely]]
  __c = _S_error();
-   else if (++_M_curr() == _M_last) [[unlikely]]
+   else if (__incr() == _M_last) [[unlikely]]
  __c = _S_error();
else
  {
-   ++__to_incr;
__c = (__c << 6) | (__u & 0x3F);
__u = *_M_curr();
 
@@ -308,8 +310,7 @@ namespace __unicode
else
  {
__c = (__c << 6) | (__u & 0x3F);
-   ++_M_curr();
-   ++__to_incr;
+   __incr();
  }
  }
  }
@@ -323,21 +324,19 @@ namespace __unicode
 
if (__u < __lo_bound_2 || __u > __hi_bound_2) [[unlikely]]
  __c = _S_error();
-   else if (++_M_curr() == _M_last) [[unlikely]]
+   else if (__incr() == _M_last) [[unlikely]]
  __c = _S_error();
else
  {
-   ++__to_incr;
__c = (__c << 6) | (__u & 0x3F);
__u = *_M_curr();
 
if (__u < __lo_bound || __u > __hi_bound) [[unlikely]]
  __c = _S_error();
-   else if (++_M_curr() == _M_last) [[unlikely]]
+   else if (__incr() == _M_last) [[unlikely]]
  __c = _S_error();
else
  {
-   ++__to_incr;
__c = (__c << 6) | (__u & 0x3F);
__u = *_M_curr();
 
@@ -346,8 +345,7 @@ namespace __unicode
else
  {
__c = (__c << 6) | (__u & 0x3F);
-   ++_M_curr();
-   ++__to_incr;
+   __incr();
  }
  }
  }
diff --git a/libstdc++-v3/testsuite/ext/unicode/view.cc 
b/libstdc++-v3/testsuite/ext/unicode/view.cc
index ee23b0b1d8a..6f3c099bd84 100644
--- a/libstdc++-v3/testsuite/ext/unicode/view.cc
+++ b/libstdc++-v3/testsuite/ext/unicode/view.cc
@@ -55,6 +55,13 @@ test_illformed_utf8()
   VERIFY( std::ranges::equal(v5, 
u8"\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\x41\uFFFD\uFFFD\x42"sv) );
   uc::_Utf8_view v6("\xe1\x80\xe2\xf0\x91\x92\xf1\xbf\x41"sv); // Table 3-11
   VERIFY( std::ranges::equal(

[committed] libstdc++: Fix for -std=c++23 -ffreestanding [PR114866]

2024-05-07 Thread Jonathan Wakely
Tested x86_64-linux. Pushed to trunk. gcc-14 backport to follow.

-- >8 --

std::shared_ptr isn't declared for freestanding, so guard uses of it
with #if _GLIBCXX_HOSTED in .

libstdc++-v3/ChangeLog:

PR libstdc++/114866
* include/bits/out_ptr.h [!_GLIBCXX_HOSTED]: Don't refer to
shared_ptr, __shared_ptr or __is_shred_ptr.
* testsuite/20_util/headers/memory/114866.cc: New test.
---
 libstdc++-v3/include/bits/out_ptr.h| 10 ++
 .../testsuite/20_util/headers/memory/114866.cc |  4 
 2 files changed, 14 insertions(+)
 create mode 100644 libstdc++-v3/testsuite/20_util/headers/memory/114866.cc

diff --git a/libstdc++-v3/include/bits/out_ptr.h 
b/libstdc++-v3/include/bits/out_ptr.h
index aeeb6640441..d74c9f52d3b 100644
--- a/libstdc++-v3/include/bits/out_ptr.h
+++ b/libstdc++-v3/include/bits/out_ptr.h
@@ -54,9 +54,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 class out_ptr_t
 {
+#if _GLIBCXX_HOSTED
   static_assert(!__is_shared_ptr<_Smart> || sizeof...(_Args) != 0,
"a deleter must be used when adapting std::shared_ptr "
"with std::out_ptr");
+#endif
 
 public:
   explicit
@@ -216,6 +218,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  [[no_unique_address]] _Del2 _M_del;
};
 
+#if _GLIBCXX_HOSTED
   // Partial specialization for std::shared_ptr.
   // This specialization gives direct access to the private member
   // of the shared_ptr, avoiding the overhead of storing a separate
@@ -274,6 +277,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
  using _Impl<_Smart, _Pointer, _Del, allocator>::_Impl;
};
+#endif
 
   using _Impl_t = _Impl<_Smart, _Pointer, _Args...>;
 
@@ -293,8 +297,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 class inout_ptr_t
 {
+#if _GLIBCXX_HOSTED
   static_assert(!__is_shared_ptr<_Smart>,
"std::inout_ptr can not be used to wrap std::shared_ptr");
+#endif
 
 public:
   explicit
@@ -320,11 +326,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   }
 
 private:
+#if _GLIBCXX_HOSTED
   // Avoid an invalid instantiation of out_ptr_t, ...>
   using _Out_ptr_t
= __conditional_t<__is_shared_ptr<_Smart>,
  out_ptr_t,
  out_ptr_t<_Smart, _Pointer, _Args...>>;
+#else
+  using _Out_ptr_t = out_ptr_t<_Smart, _Pointer, _Args...>;
+#endif
   using _Impl_t = typename _Out_ptr_t::_Impl_t;
   _Impl_t _M_impl;
 };
diff --git a/libstdc++-v3/testsuite/20_util/headers/memory/114866.cc 
b/libstdc++-v3/testsuite/20_util/headers/memory/114866.cc
new file mode 100644
index 000..7cf6be0539d
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/headers/memory/114866.cc
@@ -0,0 +1,4 @@
+// { dg-options "-ffreestanding" }
+// { dg-do compile }
+// PR libstdc++/114866  & out_ptr in freestanding
+#include 
-- 
2.44.0



[gcc r15-284] libstdc++: Fix for -std=c++23 -ffreestanding [PR114866]

2024-05-07 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:9927059bb88e966e0a45f09e4fd1193f93df708f

commit r15-284-g9927059bb88e966e0a45f09e4fd1193f93df708f
Author: Jonathan Wakely 
Date:   Thu May 2 12:14:52 2024 +0100

libstdc++: Fix  for -std=c++23 -ffreestanding [PR114866]

std::shared_ptr isn't declared for freestanding, so guard uses of it
with #if _GLIBCXX_HOSTED in .

libstdc++-v3/ChangeLog:

PR libstdc++/114866
* include/bits/out_ptr.h [!_GLIBCXX_HOSTED]: Don't refer to
shared_ptr, __shared_ptr or __is_shred_ptr.
* testsuite/20_util/headers/memory/114866.cc: New test.

Diff:
---
 libstdc++-v3/include/bits/out_ptr.h | 10 ++
 libstdc++-v3/testsuite/20_util/headers/memory/114866.cc |  4 
 2 files changed, 14 insertions(+)

diff --git a/libstdc++-v3/include/bits/out_ptr.h 
b/libstdc++-v3/include/bits/out_ptr.h
index aeeb6640441..d74c9f52d3b 100644
--- a/libstdc++-v3/include/bits/out_ptr.h
+++ b/libstdc++-v3/include/bits/out_ptr.h
@@ -54,9 +54,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 class out_ptr_t
 {
+#if _GLIBCXX_HOSTED
   static_assert(!__is_shared_ptr<_Smart> || sizeof...(_Args) != 0,
"a deleter must be used when adapting std::shared_ptr "
"with std::out_ptr");
+#endif
 
 public:
   explicit
@@ -216,6 +218,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  [[no_unique_address]] _Del2 _M_del;
};
 
+#if _GLIBCXX_HOSTED
   // Partial specialization for std::shared_ptr.
   // This specialization gives direct access to the private member
   // of the shared_ptr, avoiding the overhead of storing a separate
@@ -274,6 +277,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
  using _Impl<_Smart, _Pointer, _Del, allocator>::_Impl;
};
+#endif
 
   using _Impl_t = _Impl<_Smart, _Pointer, _Args...>;
 
@@ -293,8 +297,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 class inout_ptr_t
 {
+#if _GLIBCXX_HOSTED
   static_assert(!__is_shared_ptr<_Smart>,
"std::inout_ptr can not be used to wrap std::shared_ptr");
+#endif
 
 public:
   explicit
@@ -320,11 +326,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   }
 
 private:
+#if _GLIBCXX_HOSTED
   // Avoid an invalid instantiation of out_ptr_t, ...>
   using _Out_ptr_t
= __conditional_t<__is_shared_ptr<_Smart>,
  out_ptr_t,
  out_ptr_t<_Smart, _Pointer, _Args...>>;
+#else
+  using _Out_ptr_t = out_ptr_t<_Smart, _Pointer, _Args...>;
+#endif
   using _Impl_t = typename _Out_ptr_t::_Impl_t;
   _Impl_t _M_impl;
 };
diff --git a/libstdc++-v3/testsuite/20_util/headers/memory/114866.cc 
b/libstdc++-v3/testsuite/20_util/headers/memory/114866.cc
new file mode 100644
index 000..7cf6be0539d
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/headers/memory/114866.cc
@@ -0,0 +1,4 @@
+// { dg-options "-ffreestanding" }
+// { dg-do compile }
+// PR libstdc++/114866  & out_ptr in freestanding
+#include 


[PATCH] libstdc++: Rewrite std::variant comparisons without macros

2024-05-07 Thread Jonathan Wakely
I don't think using a macro for these really saves us much, we can do
this to avoid duplication instead. And now it's not a big, multi-line
macro that's a pain to edit.

Any objections?

Tested x86_64-linux.

-- >8 --

libstdc++-v3/ChangeLog:

* include/std/variant (__detail::__variant::__compare): New
function template.
(operator==, operator!=, operator<, operator>, operator<=)
(operator>=): Replace macro definition with handwritten function
calling __detail::__variant::__compare.
(operator<=>): Call __detail::__variant::__compare.
---
 libstdc++-v3/include/std/variant | 167 +--
 1 file changed, 114 insertions(+), 53 deletions(-)

diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant
index bf05eec9a6b..cfb4bcdbcc9 100644
--- a/libstdc++-v3/include/std/variant
+++ b/libstdc++-v3/include/std/variant
@@ -48,6 +48,7 @@
 #include 
 #include  // in_place_index_t
 #if __cplusplus >= 202002L
+# include 
 # include 
 #endif
 
@@ -1237,47 +1238,119 @@ namespace __variant
 
   struct monostate { };
 
-#if __cpp_lib_concepts
-# define _VARIANT_RELATION_FUNCTION_CONSTRAINTS(TYPES, OP) \
-  requires ((requires (const TYPES& __t) { \
-   { __t OP __t } -> __detail::__boolean_testable; }) && ...)
-#else
-# define _VARIANT_RELATION_FUNCTION_CONSTRAINTS(TYPES, OP)
-#endif
+namespace __detail::__variant
+{
+  template
+constexpr _Ret
+__compare(_Ret __ret, const _Vp& __lhs, const _Vp& __rhs, _Op __op)
+{
+  __variant::__raw_idx_visit(
+   [&__ret, &__lhs, __op] (auto&& __rhs_mem, auto __rhs_index) mutable
+   {
+ if constexpr (__rhs_index != variant_npos)
+   {
+ if (__lhs.index() == __rhs_index.value)
+   {
+ auto& __this_mem = std::get<__rhs_index>(__lhs);
+ __ret = __op(__this_mem, __rhs_mem);
+ return;
+   }
+   }
+ __ret = __op(__lhs.index() + 1, __rhs_index + 1);
+   }, __rhs);
+  return __ret;
+}
+} // namespace __detail::__variant
 
-#define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP) \
-  template \
-_VARIANT_RELATION_FUNCTION_CONSTRAINTS(_Types, __OP) \
-constexpr bool \
-operator __OP [[nodiscard]] (const variant<_Types...>& __lhs, \
-const variant<_Types...>& __rhs) \
-{ \
-  bool __ret = true; \
-  __detail::__variant::__raw_idx_visit( \
-[&__ret, &__lhs] (auto&& __rhs_mem, auto __rhs_index) mutable \
-{ \
- if constexpr (__rhs_index != variant_npos) \
-   { \
- if (__lhs.index() == __rhs_index) \
-   { \
- auto& __this_mem = std::get<__rhs_index>(__lhs);  \
-  __ret = __this_mem __OP __rhs_mem; \
- return; \
-} \
-} \
- __ret = (__lhs.index() + 1) __OP (__rhs_index + 1); \
-   }, __rhs); \
-  return __ret; \
+  template
+#if __cpp_lib_concepts
+requires ((requires (const _Types& __t) {
+  { __t == __t } -> convertible_to; }) && ...)
+#endif
+constexpr bool
+operator== [[nodiscard]] (const variant<_Types...>& __lhs,
+ const variant<_Types...>& __rhs)
+{
+  return __detail::__variant::__compare(true, __lhs, __rhs,
+   [](auto&& __l, auto&& __r) {
+ return __l == __r;
+   });
 }
 
-  _VARIANT_RELATION_FUNCTION_TEMPLATE(<)
-  _VARIANT_RELATION_FUNCTION_TEMPLATE(<=)
-  _VARIANT_RELATION_FUNCTION_TEMPLATE(==)
-  _VARIANT_RELATION_FUNCTION_TEMPLATE(!=)
-  _VARIANT_RELATION_FUNCTION_TEMPLATE(>=)
-  _VARIANT_RELATION_FUNCTION_TEMPLATE(>)
+  template
+#if __cpp_lib_concepts
+requires ((requires (const _Types& __t) {
+  { __t != __t } -> convertible_to; }) && ...)
+#endif
+constexpr bool
+operator!= [[nodiscard]] (const variant<_Types...>& __lhs,
+ const variant<_Types...>& __rhs)
+{
+  return __detail::__variant::__compare(true, __lhs, __rhs,
+   [](auto&& __l, auto&& __r) {
+ return __l != __r;
+   });
+}
 
-#undef _VARIANT_RELATION_FUNCTION_TEMPLATE
+  template
+#if __cpp_lib_concepts
+requires ((requires (const _Types& __t) {
+  { __t < __t } -> convertible_to; }) && ...)
+#endif
+constexpr bool
+operator< [[nodiscard]] (const variant<_Types...>& __lhs,
+const variant<_Types...>& __rhs)
+{
+  return __detail::__variant::__compare(true, __lhs, __rhs,
+   [](auto&& __l, auto&& __r) {
+ return __l < __r;
+   });
+}
+
+  template
+#if 

Re: [PATCH 4/4] libstdc++: Simplify std::variant comparison operators

2024-05-07 Thread Jonathan Wakely
On Wed, 10 Apr 2024 at 09:51, Jonathan Wakely wrote:
>
> Tested x86_64-linux.
>
> This is just a minor clean-up and could wait for stage 1.

Pushed now.

>
> -- >8 --
>
> libstdc++-v3/ChangeLog:
>
> * include/std/variant (_VARIANT_RELATION_FUNCTION_TEMPLATE):
> Simplify.
> ---
>  libstdc++-v3/include/std/variant | 20 +---
>  1 file changed, 9 insertions(+), 11 deletions(-)
>
> diff --git a/libstdc++-v3/include/std/variant 
> b/libstdc++-v3/include/std/variant
> index 5ba6d9d42e3..2be0f0c1db7 100644
> --- a/libstdc++-v3/include/std/variant
> +++ b/libstdc++-v3/include/std/variant
> @@ -1245,7 +1245,7 @@ namespace __variant
>  # define _VARIANT_RELATION_FUNCTION_CONSTRAINTS(TYPES, OP)
>  #endif
>
> -#define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP, __NAME) \
> +#define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP) \
>template \
>  _VARIANT_RELATION_FUNCTION_CONSTRAINTS(_Types, __OP) \
>  constexpr bool \
> @@ -1262,22 +1262,20 @@ namespace __variant
> { \
>   auto& __this_mem = std::get<__rhs_index>(__lhs);  \
>__ret = __this_mem __OP __rhs_mem; \
> + return; \
>  } \
> - else \
> -   __ret = (__lhs.index() + 1) __OP (__rhs_index + 1); \
>  } \
> -  else \
> -__ret = (__lhs.index() + 1) __OP (__rhs_index + 1); \
> + __ret = (__lhs.index() + 1) __OP (__rhs_index + 1); \
> }, __rhs); \
>return __ret; \
>  }
>
> -  _VARIANT_RELATION_FUNCTION_TEMPLATE(<, less)
> -  _VARIANT_RELATION_FUNCTION_TEMPLATE(<=, less_equal)
> -  _VARIANT_RELATION_FUNCTION_TEMPLATE(==, equal)
> -  _VARIANT_RELATION_FUNCTION_TEMPLATE(!=, not_equal)
> -  _VARIANT_RELATION_FUNCTION_TEMPLATE(>=, greater_equal)
> -  _VARIANT_RELATION_FUNCTION_TEMPLATE(>, greater)
> +  _VARIANT_RELATION_FUNCTION_TEMPLATE(<)
> +  _VARIANT_RELATION_FUNCTION_TEMPLATE(<=)
> +  _VARIANT_RELATION_FUNCTION_TEMPLATE(==)
> +  _VARIANT_RELATION_FUNCTION_TEMPLATE(!=)
> +  _VARIANT_RELATION_FUNCTION_TEMPLATE(>=)
> +  _VARIANT_RELATION_FUNCTION_TEMPLATE(>)
>
>  #undef _VARIANT_RELATION_FUNCTION_TEMPLATE
>
> --
> 2.44.0
>



[gcc r15-283] libstdc++: Simplify std::variant comparison operators

2024-05-07 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:6709e35457a30b2184fa8337aa4abdd2c0edaeb3

commit r15-283-g6709e35457a30b2184fa8337aa4abdd2c0edaeb3
Author: Jonathan Wakely 
Date:   Thu Mar 28 14:19:45 2024 +

libstdc++: Simplify std::variant comparison operators

libstdc++-v3/ChangeLog:

* include/std/variant (_VARIANT_RELATION_FUNCTION_TEMPLATE):
Simplify.

Diff:
---
 libstdc++-v3/include/std/variant | 20 +---
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant
index 8072e1f17a8..bf05eec9a6b 100644
--- a/libstdc++-v3/include/std/variant
+++ b/libstdc++-v3/include/std/variant
@@ -1245,7 +1245,7 @@ namespace __variant
 # define _VARIANT_RELATION_FUNCTION_CONSTRAINTS(TYPES, OP)
 #endif
 
-#define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP, __NAME) \
+#define _VARIANT_RELATION_FUNCTION_TEMPLATE(__OP) \
   template \
 _VARIANT_RELATION_FUNCTION_CONSTRAINTS(_Types, __OP) \
 constexpr bool \
@@ -1262,22 +1262,20 @@ namespace __variant
{ \
  auto& __this_mem = std::get<__rhs_index>(__lhs);  \
   __ret = __this_mem __OP __rhs_mem; \
+ return; \
 } \
- else \
-   __ret = (__lhs.index() + 1) __OP (__rhs_index + 1); \
 } \
-  else \
-__ret = (__lhs.index() + 1) __OP (__rhs_index + 1); \
+ __ret = (__lhs.index() + 1) __OP (__rhs_index + 1); \
}, __rhs); \
   return __ret; \
 }
 
-  _VARIANT_RELATION_FUNCTION_TEMPLATE(<, less)
-  _VARIANT_RELATION_FUNCTION_TEMPLATE(<=, less_equal)
-  _VARIANT_RELATION_FUNCTION_TEMPLATE(==, equal)
-  _VARIANT_RELATION_FUNCTION_TEMPLATE(!=, not_equal)
-  _VARIANT_RELATION_FUNCTION_TEMPLATE(>=, greater_equal)
-  _VARIANT_RELATION_FUNCTION_TEMPLATE(>, greater)
+  _VARIANT_RELATION_FUNCTION_TEMPLATE(<)
+  _VARIANT_RELATION_FUNCTION_TEMPLATE(<=)
+  _VARIANT_RELATION_FUNCTION_TEMPLATE(==)
+  _VARIANT_RELATION_FUNCTION_TEMPLATE(!=)
+  _VARIANT_RELATION_FUNCTION_TEMPLATE(>=)
+  _VARIANT_RELATION_FUNCTION_TEMPLATE(>)
 
 #undef _VARIANT_RELATION_FUNCTION_TEMPLATE


[committed] libstdc++: Constrain equality ops for std::pair, std::tuple, std::variant

2024-05-07 Thread Jonathan Wakely
Tested x86_64-linux. Pushed to trunk.

-- >8 --

Implement the changes from P2944R3 which add constraints to the
comparison operators of std::pair, std::tuple, and std::variant.

The paper also changes std::optional, but we already constrain its
comparisons using SFINAE on the return type. However, we need some
additional constraints on the [optional.comp.with.t] operators that
compare an optional with a value. The paper doesn't say to do that, but
I think it's needed because otherwise when the comparison for two
optional objects fails its constraints, the two overloads that are
supposed to be for comparing to a non-optional become the best overload
candidates, but are ambiguous (and we don't even get as far as checking
the constraints for satisfaction). I reported LWG 4072 for this.

The paper does not change std::expected, but probably should have done.
I'll submit an LWG issue about that and implement it separately.

Also add [[nodiscard]] to all these comparison operators.

libstdc++-v3/ChangeLog:

* include/bits/stl_pair.h (operator==): Add constraint.
* include/bits/version.def (constrained_equality): Define.
* include/bits/version.h: Regenerate.
* include/std/optional: Define feature test macro.
(__optional_rep_op_t): Use is_convertible_v instead of
is_convertible.
* include/std/tuple: Define feature test macro.
(operator==, __tuple_cmp, operator<=>): Reimplement C++20
comparisons using lambdas. Add constraints.
* include/std/utility: Define feature test macro.
* include/std/variant: Define feature test macro.
(_VARIANT_RELATION_FUNCTION_TEMPLATE): Add constraints.
(variant): Remove unnecessary friend declarations for comparison
operators.
* testsuite/20_util/optional/relops/constrained.cc: New test.
* testsuite/20_util/pair/comparison_operators/constrained.cc:
New test.
* testsuite/20_util/tuple/comparison_operators/constrained.cc:
New test.
* testsuite/20_util/variant/relops/constrained.cc: New test.
* testsuite/20_util/tuple/comparison_operators/overloaded.cc:
Disable for C++20 and later.
* testsuite/20_util/tuple/comparison_operators/overloaded2.cc:
Remove dg-error line for target c++20.
---
 libstdc++-v3/include/bits/stl_pair.h  |  16 +-
 libstdc++-v3/include/bits/version.def |   9 +
 libstdc++-v3/include/bits/version.h   |  10 +
 libstdc++-v3/include/std/optional |  50 +++-
 libstdc++-v3/include/std/tuple| 102 ---
 libstdc++-v3/include/std/utility  |   1 +
 libstdc++-v3/include/std/variant  |  28 +-
 .../20_util/optional/relops/constrained.cc| 258 ++
 .../pair/comparison_operators/constrained.cc  |  48 
 .../tuple/comparison_operators/constrained.cc |  50 
 .../tuple/comparison_operators/overloaded.cc  |   6 +-
 .../tuple/comparison_operators/overloaded2.cc |   1 -
 .../20_util/variant/relops/constrained.cc | 175 
 13 files changed, 679 insertions(+), 75 deletions(-)
 create mode 100644 
libstdc++-v3/testsuite/20_util/optional/relops/constrained.cc
 create mode 100644 
libstdc++-v3/testsuite/20_util/pair/comparison_operators/constrained.cc
 create mode 100644 
libstdc++-v3/testsuite/20_util/tuple/comparison_operators/constrained.cc
 create mode 100644 libstdc++-v3/testsuite/20_util/variant/relops/constrained.cc

diff --git a/libstdc++-v3/include/bits/stl_pair.h 
b/libstdc++-v3/include/bits/stl_pair.h
index 45317417c9c..0c1e5719a1a 100644
--- a/libstdc++-v3/include/bits/stl_pair.h
+++ b/libstdc++-v3/include/bits/stl_pair.h
@@ -1000,14 +1000,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template pair(_T1, _T2) -> pair<_T1, _T2>;
 #endif
 
-#if __cpp_lib_three_way_comparison && __cpp_lib_concepts
+#if __cpp_lib_three_way_comparison
   // _GLIBCXX_RESOLVE_LIB_DEFECTS
   // 3865. Sorting a range of pairs
 
   /// Two pairs are equal iff their members are equal.
   template
-inline _GLIBCXX_CONSTEXPR bool
+[[nodiscard]]
+constexpr bool
 operator==(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y)
+requires requires {
+  { __x.first == __y.first } -> __detail::__boolean_testable;
+  { __x.second == __y.second } -> __detail::__boolean_testable;
+}
 { return __x.first == __y.first && __x.second == __y.second; }
 
   /** Defines a lexicographical order for pairs.
@@ -1018,6 +1023,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* less than `Q.second`.
   */
   template
+[[nodiscard]]
 constexpr common_comparison_category_t<__detail::__synth3way_t<_T1, _U1>,
   __detail::__synth3way_t<_T2, _U2>>
 operator<=>(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y)
@@ -1029,6 +1035,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #else
   /// Two pairs of the same type are equal iff their members are equal.
   template
+

[gcc r15-279] libstdc++: Constrain equality ops for std::pair, std::tuple, std::variant

2024-05-07 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:b72e7addf855aed66c0922f17efc85f26193f801

commit r15-279-gb72e7addf855aed66c0922f17efc85f26193f801
Author: Jonathan Wakely 
Date:   Wed Mar 27 15:24:05 2024 +

libstdc++: Constrain equality ops for std::pair, std::tuple, std::variant

Implement the changes from P2944R3 which add constraints to the
comparison operators of std::pair, std::tuple, and std::variant.

The paper also changes std::optional, but we already constrain its
comparisons using SFINAE on the return type. However, we need some
additional constraints on the [optional.comp.with.t] operators that
compare an optional with a value. The paper doesn't say to do that, but
I think it's needed because otherwise when the comparison for two
optional objects fails its constraints, the two overloads that are
supposed to be for comparing to a non-optional become the best overload
candidates, but are ambiguous (and we don't even get as far as checking
the constraints for satisfaction). I reported LWG 4072 for this.

The paper does not change std::expected, but probably should have done.
I'll submit an LWG issue about that and implement it separately.

Also add [[nodiscard]] to all these comparison operators.

libstdc++-v3/ChangeLog:

* include/bits/stl_pair.h (operator==): Add constraint.
* include/bits/version.def (constrained_equality): Define.
* include/bits/version.h: Regenerate.
* include/std/optional: Define feature test macro.
(__optional_rep_op_t): Use is_convertible_v instead of
is_convertible.
* include/std/tuple: Define feature test macro.
(operator==, __tuple_cmp, operator<=>): Reimplement C++20
comparisons using lambdas. Add constraints.
* include/std/utility: Define feature test macro.
* include/std/variant: Define feature test macro.
(_VARIANT_RELATION_FUNCTION_TEMPLATE): Add constraints.
(variant): Remove unnecessary friend declarations for comparison
operators.
* testsuite/20_util/optional/relops/constrained.cc: New test.
* testsuite/20_util/pair/comparison_operators/constrained.cc:
New test.
* testsuite/20_util/tuple/comparison_operators/constrained.cc:
New test.
* testsuite/20_util/variant/relops/constrained.cc: New test.
* testsuite/20_util/tuple/comparison_operators/overloaded.cc:
Disable for C++20 and later.
* testsuite/20_util/tuple/comparison_operators/overloaded2.cc:
Remove dg-error line for target c++20.

Diff:
---
 libstdc++-v3/include/bits/stl_pair.h   |  16 +-
 libstdc++-v3/include/bits/version.def  |   9 +
 libstdc++-v3/include/bits/version.h|  10 +
 libstdc++-v3/include/std/optional  |  50 ++--
 libstdc++-v3/include/std/tuple | 102 
 libstdc++-v3/include/std/utility   |   1 +
 libstdc++-v3/include/std/variant   |  28 +--
 .../20_util/optional/relops/constrained.cc | 258 +
 .../pair/comparison_operators/constrained.cc   |  48 
 .../tuple/comparison_operators/constrained.cc  |  50 
 .../tuple/comparison_operators/overloaded.cc   |   6 +-
 .../tuple/comparison_operators/overloaded2.cc  |   1 -
 .../20_util/variant/relops/constrained.cc  | 175 ++
 13 files changed, 679 insertions(+), 75 deletions(-)

diff --git a/libstdc++-v3/include/bits/stl_pair.h 
b/libstdc++-v3/include/bits/stl_pair.h
index 45317417c9c..0c1e5719a1a 100644
--- a/libstdc++-v3/include/bits/stl_pair.h
+++ b/libstdc++-v3/include/bits/stl_pair.h
@@ -1000,14 +1000,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template pair(_T1, _T2) -> pair<_T1, _T2>;
 #endif
 
-#if __cpp_lib_three_way_comparison && __cpp_lib_concepts
+#if __cpp_lib_three_way_comparison
   // _GLIBCXX_RESOLVE_LIB_DEFECTS
   // 3865. Sorting a range of pairs
 
   /// Two pairs are equal iff their members are equal.
   template
-inline _GLIBCXX_CONSTEXPR bool
+[[nodiscard]]
+constexpr bool
 operator==(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y)
+requires requires {
+  { __x.first == __y.first } -> __detail::__boolean_testable;
+  { __x.second == __y.second } -> __detail::__boolean_testable;
+}
 { return __x.first == __y.first && __x.second == __y.second; }
 
   /** Defines a lexicographical order for pairs.
@@ -1018,6 +1023,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* less than `Q.second`.
   */
   template
+[[nodiscard]]
 constexpr common_comparison_category_t<__detail::__synth3way_t<_T1, _U1>,
   __detail::__synth3way_t<_T2, _U2>>
 operator&

[committed] libstdc++: Use https instead of http in some comments

2024-05-07 Thread Jonathan Wakely
Tested x86_64-linux. Pushed to trunk.

-- >8 --

libstdc++-v3/ChangeLog:

* include/backward/auto_ptr.h: Use https for URL in comment.
* include/bits/basic_ios.h: Likewise.
* include/std/iostream: Likewise.
---
 libstdc++-v3/include/backward/auto_ptr.h | 2 +-
 libstdc++-v3/include/bits/basic_ios.h| 6 +++---
 libstdc++-v3/include/std/iostream| 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/libstdc++-v3/include/backward/auto_ptr.h 
b/libstdc++-v3/include/backward/auto_ptr.h
index dccd459f1e5..271a64d1de0 100644
--- a/libstdc++-v3/include/backward/auto_ptr.h
+++ b/libstdc++-v3/include/backward/auto_ptr.h
@@ -265,7 +265,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  @endcode
*
*  But it doesn't work, and won't be fixed. For further details see
-   *  http://cplusplus.github.io/LWG/lwg-closed.html#463
+   *  https://cplusplus.github.io/LWG/lwg-closed.html#463
*/
   auto_ptr(auto_ptr_ref __ref) throw()
   : _M_ptr(__ref._M_ptr) { }
diff --git a/libstdc++-v3/include/bits/basic_ios.h 
b/libstdc++-v3/include/bits/basic_ios.h
index 44a77149112..258e6042b8f 100644
--- a/libstdc++-v3/include/bits/basic_ios.h
+++ b/libstdc++-v3/include/bits/basic_ios.h
@@ -408,7 +408,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  with this stream, calls that buffer's @c pubimbue(loc).
*
*  Additional l10n notes are at
-   *  http://gcc.gnu.org/onlinedocs/libstdc++/manual/localization.html
+   *  https://gcc.gnu.org/onlinedocs/libstdc++/manual/localization.html
   */
   locale
   imbue(const locale& __loc);
@@ -428,7 +428,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  @endcode
*
*  Additional l10n notes are at
-   *  http://gcc.gnu.org/onlinedocs/libstdc++/manual/localization.html
+   *  https://gcc.gnu.org/onlinedocs/libstdc++/manual/localization.html
   */
   char
   narrow(char_type __c, char __dfault) const
@@ -447,7 +447,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  @endcode
*
*  Additional l10n notes are at
-   *  http://gcc.gnu.org/onlinedocs/libstdc++/manual/localization.html
+   *  https://gcc.gnu.org/onlinedocs/libstdc++/manual/localization.html
   */
   char_type
   widen(char __c) const
diff --git a/libstdc++-v3/include/std/iostream 
b/libstdc++-v3/include/std/iostream
index 0c6a2d8a4b3..4f4fa6880d5 100644
--- a/libstdc++-v3/include/std/iostream
+++ b/libstdc++-v3/include/std/iostream
@@ -50,7 +50,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
*  The `` header declares the eight *standard stream objects*.
*  For other declarations, see
-   *  http://gcc.gnu.org/onlinedocs/libstdc++/manual/io.html
+   *  https://gcc.gnu.org/onlinedocs/libstdc++/manual/io.html
*  and the @link iosfwd I/O forward declarations @endlink
*
*  They are required by default to cooperate with the global C
-- 
2.44.0



[committed] libstdc++: Update ABI test to disallow adding to released symbol versions

2024-05-07 Thread Jonathan Wakely
Tested x86_64-linux. Pushed to trunk.

-- >8 --

If we update the list of "active" symbols versions now, rather than when
adding a new symbol version, we will notice if new symbols get added to
the wrong version (as in PR 114692).

libstdc++-v3/ChangeLog:

* testsuite/util/testsuite_abi.cc: Update latest versions to
new versions that should be used in future.
---
 libstdc++-v3/testsuite/util/testsuite_abi.cc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/testsuite/util/testsuite_abi.cc 
b/libstdc++-v3/testsuite/util/testsuite_abi.cc
index e4bf3cdc8e0..ec7c3df9ecc 100644
--- a/libstdc++-v3/testsuite/util/testsuite_abi.cc
+++ b/libstdc++-v3/testsuite/util/testsuite_abi.cc
@@ -254,8 +254,8 @@ check_version(symbol& test, bool added)
test.version_status = symbol::incompatible;
 
   // Check that added symbols are added in the latest pre-release version.
-  bool latestp = (test.version_name == "GLIBCXX_3.4.33"
-|| test.version_name == "CXXABI_1.3.15"
+  bool latestp = (test.version_name == "GLIBCXX_3.4.34"
+|| test.version_name == "CXXABI_1.3.16"
 || test.version_name == "CXXABI_FLOAT128"
 || test.version_name == "CXXABI_TM_1");
   if (added && !latestp)
-- 
2.44.0



[gcc r15-278] libstdc++: Use https instead of http in some comments

2024-05-07 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:9ebd123432873edf1551006be07381150fd617ea

commit r15-278-g9ebd123432873edf1551006be07381150fd617ea
Author: Jonathan Wakely 
Date:   Fri May 3 18:14:09 2024 +0100

libstdc++: Use https instead of http in some comments

libstdc++-v3/ChangeLog:

* include/backward/auto_ptr.h: Use https for URL in comment.
* include/bits/basic_ios.h: Likewise.
* include/std/iostream: Likewise.

Diff:
---
 libstdc++-v3/include/backward/auto_ptr.h | 2 +-
 libstdc++-v3/include/bits/basic_ios.h| 6 +++---
 libstdc++-v3/include/std/iostream| 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/libstdc++-v3/include/backward/auto_ptr.h 
b/libstdc++-v3/include/backward/auto_ptr.h
index dccd459f1e5..271a64d1de0 100644
--- a/libstdc++-v3/include/backward/auto_ptr.h
+++ b/libstdc++-v3/include/backward/auto_ptr.h
@@ -265,7 +265,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  @endcode
*
*  But it doesn't work, and won't be fixed. For further details see
-   *  http://cplusplus.github.io/LWG/lwg-closed.html#463
+   *  https://cplusplus.github.io/LWG/lwg-closed.html#463
*/
   auto_ptr(auto_ptr_ref __ref) throw()
   : _M_ptr(__ref._M_ptr) { }
diff --git a/libstdc++-v3/include/bits/basic_ios.h 
b/libstdc++-v3/include/bits/basic_ios.h
index 44a77149112..258e6042b8f 100644
--- a/libstdc++-v3/include/bits/basic_ios.h
+++ b/libstdc++-v3/include/bits/basic_ios.h
@@ -408,7 +408,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  with this stream, calls that buffer's @c pubimbue(loc).
*
*  Additional l10n notes are at
-   *  http://gcc.gnu.org/onlinedocs/libstdc++/manual/localization.html
+   *  https://gcc.gnu.org/onlinedocs/libstdc++/manual/localization.html
   */
   locale
   imbue(const locale& __loc);
@@ -428,7 +428,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  @endcode
*
*  Additional l10n notes are at
-   *  http://gcc.gnu.org/onlinedocs/libstdc++/manual/localization.html
+   *  https://gcc.gnu.org/onlinedocs/libstdc++/manual/localization.html
   */
   char
   narrow(char_type __c, char __dfault) const
@@ -447,7 +447,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  @endcode
*
*  Additional l10n notes are at
-   *  http://gcc.gnu.org/onlinedocs/libstdc++/manual/localization.html
+   *  https://gcc.gnu.org/onlinedocs/libstdc++/manual/localization.html
   */
   char_type
   widen(char __c) const
diff --git a/libstdc++-v3/include/std/iostream 
b/libstdc++-v3/include/std/iostream
index 0c6a2d8a4b3..4f4fa6880d5 100644
--- a/libstdc++-v3/include/std/iostream
+++ b/libstdc++-v3/include/std/iostream
@@ -50,7 +50,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
*  The `` header declares the eight *standard stream objects*.
*  For other declarations, see
-   *  http://gcc.gnu.org/onlinedocs/libstdc++/manual/io.html
+   *  https://gcc.gnu.org/onlinedocs/libstdc++/manual/io.html
*  and the @link iosfwd I/O forward declarations @endlink
*
*  They are required by default to cooperate with the global C


[gcc r15-277] libstdc++: Update ABI test to disallow adding to released symbol versions

2024-05-07 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:6e25ca387fbbb412a2e498e28ea5db28e033a318

commit r15-277-g6e25ca387fbbb412a2e498e28ea5db28e033a318
Author: Jonathan Wakely 
Date:   Thu Apr 11 15:35:11 2024 +0100

libstdc++: Update ABI test to disallow adding to released symbol versions

If we update the list of "active" symbols versions now, rather than when
adding a new symbol version, we will notice if new symbols get added to
the wrong version (as in PR 114692).

libstdc++-v3/ChangeLog:

* testsuite/util/testsuite_abi.cc: Update latest versions to
new versions that should be used in future.

Diff:
---
 libstdc++-v3/testsuite/util/testsuite_abi.cc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/testsuite/util/testsuite_abi.cc 
b/libstdc++-v3/testsuite/util/testsuite_abi.cc
index e4bf3cdc8e0..ec7c3df9ecc 100644
--- a/libstdc++-v3/testsuite/util/testsuite_abi.cc
+++ b/libstdc++-v3/testsuite/util/testsuite_abi.cc
@@ -254,8 +254,8 @@ check_version(symbol& test, bool added)
test.version_status = symbol::incompatible;
 
   // Check that added symbols are added in the latest pre-release version.
-  bool latestp = (test.version_name == "GLIBCXX_3.4.33"
-|| test.version_name == "CXXABI_1.3.15"
+  bool latestp = (test.version_name == "GLIBCXX_3.4.34"
+|| test.version_name == "CXXABI_1.3.16"
 || test.version_name == "CXXABI_FLOAT128"
 || test.version_name == "CXXABI_TM_1");
   if (added && !latestp)


Re: [PATCHv2 wwwdocs 1/1] gcc-14: document P1689R5 scanning output support

2024-05-07 Thread Jonathan Wakely
On Thu, 2 May 2024 at 19:03, Ben Boeckel  wrote:
>
> On Tue, Apr 30, 2024 at 10:24:44 +0100, Jonathan Wakely wrote:
> > On 20/11/23 11:22 -0500, Ben Boeckel wrote:
> > >---
> > > htdocs/gcc-14/changes.html | 11 +++
> > > 1 file changed, 11 insertions(+)
> > >
> > >diff --git a/htdocs/gcc-14/changes.html b/htdocs/gcc-14/changes.html
> > >index 7278f753..b506eeb1 100644
> > >--- a/htdocs/gcc-14/changes.html
> > >+++ b/htdocs/gcc-14/changes.html
> > >@@ -112,6 +112,17 @@ a work-in-progress.
> > >   
> > > 
> > >   
> > >+  C++ module scanning for named modules is now available:
> > >+
> > >+  https://wg21.link/P1689R5;>P1689R5, Format for
> > >+  describing dependencies of source files.
> > >+  
> > >+  The -fdeps-format=, -fdeps-file=, and
> > >+  -fdeps=target= flags may be used to generate P1689 
> > >output
> >
> > This should be -fdeps-target= not -fdeps=target=.
>
> Whoops, yep.
>
> > >+  (the p1689r5 format is the only available format 
> > >today).
> >
> > I wish the option was more descriptive than "p1689r5", which nobody is
> > going to remember (but I assume we don't actually need to specify it
> > explicitly since it's the only supported format).
>
> All users of the flag should be having it in the build system itself;
> hand-coded makefiles can use it, but will need considerable `jq`
> gymnastics to turn the output into properly understood make syntax
> snippets for their build.
>
> > >+  
> > >+
> >
> > Do we need a list for this item? It seems a bit weird that the first
> > list item is just the paper  How about just a single paragraph?
> >
> > C++ module scanning for named modules is now available, based on the
> > format described in https://wg21.link/P1689R5;>P1689R5,
> > Format for describing dependencies of source files. The
> > -fdeps-format=, -fdeps-file=, and
> > -fdeps-target= flags may be used to generate dependency
> > information. In GCC 14 p1689r5 is the only valid argument
> > for -fdeps-format=.
>
> Sounds good. New patch attached.

Thanks, Ben. I reformatted the whitespace so all the lines were under
80 columns and pushed it to wwwdocs.



gcc-wwwdocs branch master updated. 8ee66061ef0ec3fb5593dc42cf04aaee1c5d5e1e

2024-05-07 Thread Jonathan Wakely via Gcc-cvs-wwwdocs
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "gcc-wwwdocs".

The branch, master has been updated
   via  8ee66061ef0ec3fb5593dc42cf04aaee1c5d5e1e (commit)
  from  1aef08f66802bbddaf9a048a1840e26597e4f62e (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -
commit 8ee66061ef0ec3fb5593dc42cf04aaee1c5d5e1e
Author: Ben Boeckel 
Date:   Tue May 7 11:01:17 2024 +0100

gcc-14: document P1689R5 scanning output support

diff --git a/htdocs/gcc-14/changes.html b/htdocs/gcc-14/changes.html
index 2a4b2f12..ca5174de 100644
--- a/htdocs/gcc-14/changes.html
+++ b/htdocs/gcc-14/changes.html
@@ -515,6 +515,13 @@ You may also want to check out our
   GCC supports a new pragma pragma GCC novector to
   indicate to the vectorizer not to vectorize the loop annotated with the
   pragma.
+  C++ module scanning for named modules is now available, based on the
+format described in https://wg21.link/P1689R5;>P1689R5,
+Format for describing dependencies of source files.
+The -fdeps-format=, -fdeps-file=, and
+-fdeps-target= flags may be used to generate dependency
+information. In GCC 14 p1689r5 is the only valid argument
+for -fdeps-format=.
 
 
 Runtime Library (libstdc++)

---

Summary of changes:
 htdocs/gcc-14/changes.html | 7 +++
 1 file changed, 7 insertions(+)


hooks/post-receive
-- 
gcc-wwwdocs


gcc-wwwdocs branch master updated. ced576434ed310d0afee01d88d0c56f78b4d04c5

2024-05-03 Thread Jonathan Wakely via Gcc-cvs-wwwdocs
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "gcc-wwwdocs".

The branch, master has been updated
   via  ced576434ed310d0afee01d88d0c56f78b4d04c5 (commit)
  from  d63b0ce2968ddaa335a679ba4595ca582ef76d6d (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -
commit ced576434ed310d0afee01d88d0c56f78b4d04c5
Author: Jonathan Wakely 
Date:   Fri May 3 16:04:49 2024 +0100

Add caveat to GCC 14 release notes about C warnings-as-errors change

diff --git a/htdocs/gcc-14/changes.html b/htdocs/gcc-14/changes.html
index 46a0266d..82906de1 100644
--- a/htdocs/gcc-14/changes.html
+++ b/htdocs/gcc-14/changes.html
@@ -40,6 +40,11 @@ a work-in-progress.
   https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wflex-array-member-not-at-end;>-Wflex-array-member-not-at-end
 to
   identify all such cases in the source code and modify them.
   
+  C:
+  Certain warnings about are now errors, see
+  Porting to GCC 14
+  for details.
+  
   https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html;>-fcf-protection=[full|branch|return|none|check]
   is refactored, to override -fcf-protection,
   -fcf-protection=none needs to be added and then

---

Summary of changes:
 htdocs/gcc-14/changes.html | 5 +
 1 file changed, 5 insertions(+)


hooks/post-receive
-- 
gcc-wwwdocs


Re: [PATCH v2] gcc-14: Mention that some warnings are now errors

2024-05-03 Thread Jonathan Wakely

On 02/05/24 16:29 +0200, Sebastian Huber wrote:

On 24.04.24 14:28, Sebastian Huber wrote:

- Am 15. Apr 2024 um 8:05 schrieb Sebastian Huber 
sebastian.hu...@embedded-brains.de:


---
v2: Remove listing of options.

htdocs/gcc-14/changes.html | 2 ++
1 file changed, 2 insertions(+)

diff --git a/htdocs/gcc-14/changes.html b/htdocs/gcc-14/changes.html
index 8ac08e9a..665d050a 100644
--- a/htdocs/gcc-14/changes.html
+++ b/htdocs/gcc-14/changes.html
@@ -231,6 +231,8 @@ a work-in-progress.
  previous options -std=c2x, -std=gnu2x
  and -Wc11-c2x-compat, which are deprecated but remain
  supported.
+  Some warnings are now errors by default (see also
+  Porting to GCC 14).


C++
--
2.35.3


Ping.


I think it would be helpful to reference this change in the C section. 
This warning to error change causes some issues with legacy software.


I agree it should be mentioned, but I would put it in the caveats
section at the top, not as the last item of the C section.

How about this? OK for wwwdocs?

-- >8 --

commit fe5fd75ea5a7a08eee0831cadbdd05689e9408db
Author: Jonathan Wakely 
Date:   Fri May 3 16:04:49 2024 +0100

Add caveat to GCC 14 release notes about C warnings-as-errors change

diff --git a/htdocs/gcc-14/changes.html b/htdocs/gcc-14/changes.html
index 46a0266d..82906de1 100644
--- a/htdocs/gcc-14/changes.html
+++ b/htdocs/gcc-14/changes.html
@@ -40,6 +40,11 @@ a work-in-progress.
   https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wflex-array-member-not-at-end;>-Wflex-array-member-not-at-end
 to
   identify all such cases in the source code and modify them.
   
+  C:
+  Certain warnings about are now errors, see
+  Porting to GCC 14
+  for details.
+  
   https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html;>-fcf-protection=[full|branch|return|none|check]
   is refactored, to override -fcf-protection,
   -fcf-protection=none needs to be added and then



Re: [PATCH] libstdc++: Update powerpc-linux-gnu baseline_symbols

2024-05-03 Thread Jonathan Wakely
On Fri, 3 May 2024 at 11:51, Jonathan Wakely  wrote:
>
> On Fri, 3 May 2024 at 10:30, Andreas Schwab wrote:
> >
> > * config/abi/post/powerpc-linux-gnu/baseline_symbols.txt: Update.
> > * config/abi/post/powerpc64-linux-gnu/32/baseline_symbols.txt: 
> > Update.
>
> OK thanks

Also OK for gcc-14 as far as I'm concerned, but it needs RM approval
for that now.


>
>
> > ---
> >  .../powerpc-linux-gnu/baseline_symbols.txt| 98 +++
> >  .../32/baseline_symbols.txt   | 98 +++
> >  2 files changed, 196 insertions(+)
> >
> > diff --git 
> > a/libstdc++-v3/config/abi/post/powerpc-linux-gnu/baseline_symbols.txt 
> > b/libstdc++-v3/config/abi/post/powerpc-linux-gnu/baseline_symbols.txt
> > index 0209003243a..c38386543b6 100644
> > --- a/libstdc++-v3/config/abi/post/powerpc-linux-gnu/baseline_symbols.txt
> > +++ b/libstdc++-v3/config/abi/post/powerpc-linux-gnu/baseline_symbols.txt
> > @@ -497,7 +497,12 @@ FUNC:_ZNKSt11__timepunctIwE7_M_daysEPPKw@@GLIBCXX_3.4
> >  FUNC:_ZNKSt11__timepunctIwE8_M_am_pmEPPKw@@GLIBCXX_3.4
> >  FUNC:_ZNKSt11__timepunctIwE9_M_monthsEPPKw@@GLIBCXX_3.4
> >  FUNC:_ZNKSt11logic_error4whatEv@@GLIBCXX_3.4
> > +FUNC:_ZNKSt12__basic_fileIcE13native_handleEv@@GLIBCXX_3.4.33
> >  FUNC:_ZNKSt12__basic_fileIcE7is_openEv@@GLIBCXX_3.4
> > +FUNC:_ZNKSt12__shared_ptrINSt10filesystem28recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEcvbEv@@GLIBCXX_3.4.31
> > +FUNC:_ZNKSt12__shared_ptrINSt10filesystem4_DirELN9__gnu_cxx12_Lock_policyE2EEcvbEv@@GLIBCXX_3.4.31
> > +FUNC:_ZNKSt12__shared_ptrINSt10filesystem7__cxx1128recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEcvbEv@@GLIBCXX_3.4.31
> > +FUNC:_ZNKSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEcvbEv@@GLIBCXX_3.4.31
> >  FUNC:_ZNKSt12bad_weak_ptr4whatEv@@GLIBCXX_3.4.15
> >  FUNC:_ZNKSt12future_error4whatEv@@GLIBCXX_3.4.14
> >  FUNC:_ZNKSt12strstreambuf6pcountEv@@GLIBCXX_3.4
> > @@ -810,6 +815,13 @@ FUNC:_ZNKSt5ctypeIwE8do_widenEPKcS2_Pw@@GLIBCXX_3.4
> >  FUNC:_ZNKSt5ctypeIwE8do_widenEc@@GLIBCXX_3.4
> >  FUNC:_ZNKSt5ctypeIwE9do_narrowEPKwS2_cPc@@GLIBCXX_3.4
> >  FUNC:_ZNKSt5ctypeIwE9do_narrowEwc@@GLIBCXX_3.4
> > +FUNC:_ZNKSt6chrono4tzdb11locate_zoneESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.31
> > +FUNC:_ZNKSt6chrono4tzdb12current_zoneEv@@GLIBCXX_3.4.31
> > +FUNC:_ZNKSt6chrono9time_zone15_M_get_sys_infoENS_10time_pointINS_3_V212system_clockENS_8durationIxSt5ratioILx1ELx1EE@@GLIBCXX_3.4.31
> > +FUNC:_ZNKSt6chrono9time_zone17_M_get_local_infoENS_10time_pointINS_7local_tENS_8durationIxSt5ratioILx1ELx1EE@@GLIBCXX_3.4.31
> > +FUNC:_ZNKSt6chrono9tzdb_list14const_iteratordeEv@@GLIBCXX_3.4.31
> > +FUNC:_ZNKSt6chrono9tzdb_list5beginEv@@GLIBCXX_3.4.31
> > +FUNC:_ZNKSt6chrono9tzdb_list5frontEv@@GLIBCXX_3.4.31
> >  FUNC:_ZNKSt6locale2id5_M_idEv@@GLIBCXX_3.4
> >  FUNC:_ZNKSt6locale4nameB5cxx11Ev@@GLIBCXX_3.4.21
> >  FUNC:_ZNKSt6locale4nameEv@@GLIBCXX_3.4
> > @@ -3285,9 +3297,18 @@ 
> > FUNC:_ZNSt6__norm15_List_node_base7_M_hookEPS0_@@GLIBCXX_3.4.14
> >  FUNC:_ZNSt6__norm15_List_node_base7reverseEv@@GLIBCXX_3.4.9
> >  FUNC:_ZNSt6__norm15_List_node_base8transferEPS0_S1_@@GLIBCXX_3.4.9
> >  FUNC:_ZNSt6__norm15_List_node_base9_M_unhookEv@@GLIBCXX_3.4.14
> > +FUNC:_ZNSt6chrono11locate_zoneESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.31
> > +FUNC:_ZNSt6chrono11reload_tzdbEv@@GLIBCXX_3.4.31
> > +FUNC:_ZNSt6chrono12current_zoneEv@@GLIBCXX_3.4.31
> >  FUNC:_ZNSt6chrono12system_clock3nowEv@@GLIBCXX_3.4.11
> > +FUNC:_ZNSt6chrono13get_tzdb_listEv@@GLIBCXX_3.4.31
> > +FUNC:_ZNSt6chrono14remote_versionB5cxx11Ev@@GLIBCXX_3.4.31
> >  FUNC:_ZNSt6chrono3_V212steady_clock3nowEv@@GLIBCXX_3.4.19
> >  FUNC:_ZNSt6chrono3_V212system_clock3nowEv@@GLIBCXX_3.4.19
> > +FUNC:_ZNSt6chrono8get_tzdbEv@@GLIBCXX_3.4.31
> > +FUNC:_ZNSt6chrono9tzdb_list11erase_afterENS0_14const_iteratorE@@GLIBCXX_3.4.31
> > +FUNC:_ZNSt6chrono9tzdb_list14const_iteratorppEi@@GLIBCXX_3.4.31
> > +FUNC:_ZNSt6chrono9tzdb_list14const_iteratorppEv@@GLIBCXX_3.4.31
> >  FUNC:_ZNSt6gslice8_IndexerC1EjRKSt8valarrayIjES4_@@GLIBCXX_3.4
> >  FUNC:_ZNSt6gslice8_IndexerC2EjRKSt8valarrayIjES4_@@GLIBCXX_3.4
> >  FUNC:_ZNSt6locale11_M_coalesceERKS_S1_i@@GLIBCXX_3.4
> > @@ -3384,6 +3405,7 @@ 
> > FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE10_M_disposeEv@@GLIBCX
> >  
> > FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE10_M_replaceEjjPKcj@@GLIBCXX_3.4.21
> >  
> > FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE10_S_

Re: [PATCH] libstdc++: Update powerpc-linux-gnu baseline_symbols

2024-05-03 Thread Jonathan Wakely
On Fri, 3 May 2024 at 10:30, Andreas Schwab wrote:
>
> * config/abi/post/powerpc-linux-gnu/baseline_symbols.txt: Update.
> * config/abi/post/powerpc64-linux-gnu/32/baseline_symbols.txt: Update.

OK thanks


> ---
>  .../powerpc-linux-gnu/baseline_symbols.txt| 98 +++
>  .../32/baseline_symbols.txt   | 98 +++
>  2 files changed, 196 insertions(+)
>
> diff --git 
> a/libstdc++-v3/config/abi/post/powerpc-linux-gnu/baseline_symbols.txt 
> b/libstdc++-v3/config/abi/post/powerpc-linux-gnu/baseline_symbols.txt
> index 0209003243a..c38386543b6 100644
> --- a/libstdc++-v3/config/abi/post/powerpc-linux-gnu/baseline_symbols.txt
> +++ b/libstdc++-v3/config/abi/post/powerpc-linux-gnu/baseline_symbols.txt
> @@ -497,7 +497,12 @@ FUNC:_ZNKSt11__timepunctIwE7_M_daysEPPKw@@GLIBCXX_3.4
>  FUNC:_ZNKSt11__timepunctIwE8_M_am_pmEPPKw@@GLIBCXX_3.4
>  FUNC:_ZNKSt11__timepunctIwE9_M_monthsEPPKw@@GLIBCXX_3.4
>  FUNC:_ZNKSt11logic_error4whatEv@@GLIBCXX_3.4
> +FUNC:_ZNKSt12__basic_fileIcE13native_handleEv@@GLIBCXX_3.4.33
>  FUNC:_ZNKSt12__basic_fileIcE7is_openEv@@GLIBCXX_3.4
> +FUNC:_ZNKSt12__shared_ptrINSt10filesystem28recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEcvbEv@@GLIBCXX_3.4.31
> +FUNC:_ZNKSt12__shared_ptrINSt10filesystem4_DirELN9__gnu_cxx12_Lock_policyE2EEcvbEv@@GLIBCXX_3.4.31
> +FUNC:_ZNKSt12__shared_ptrINSt10filesystem7__cxx1128recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEcvbEv@@GLIBCXX_3.4.31
> +FUNC:_ZNKSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEcvbEv@@GLIBCXX_3.4.31
>  FUNC:_ZNKSt12bad_weak_ptr4whatEv@@GLIBCXX_3.4.15
>  FUNC:_ZNKSt12future_error4whatEv@@GLIBCXX_3.4.14
>  FUNC:_ZNKSt12strstreambuf6pcountEv@@GLIBCXX_3.4
> @@ -810,6 +815,13 @@ FUNC:_ZNKSt5ctypeIwE8do_widenEPKcS2_Pw@@GLIBCXX_3.4
>  FUNC:_ZNKSt5ctypeIwE8do_widenEc@@GLIBCXX_3.4
>  FUNC:_ZNKSt5ctypeIwE9do_narrowEPKwS2_cPc@@GLIBCXX_3.4
>  FUNC:_ZNKSt5ctypeIwE9do_narrowEwc@@GLIBCXX_3.4
> +FUNC:_ZNKSt6chrono4tzdb11locate_zoneESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.31
> +FUNC:_ZNKSt6chrono4tzdb12current_zoneEv@@GLIBCXX_3.4.31
> +FUNC:_ZNKSt6chrono9time_zone15_M_get_sys_infoENS_10time_pointINS_3_V212system_clockENS_8durationIxSt5ratioILx1ELx1EE@@GLIBCXX_3.4.31
> +FUNC:_ZNKSt6chrono9time_zone17_M_get_local_infoENS_10time_pointINS_7local_tENS_8durationIxSt5ratioILx1ELx1EE@@GLIBCXX_3.4.31
> +FUNC:_ZNKSt6chrono9tzdb_list14const_iteratordeEv@@GLIBCXX_3.4.31
> +FUNC:_ZNKSt6chrono9tzdb_list5beginEv@@GLIBCXX_3.4.31
> +FUNC:_ZNKSt6chrono9tzdb_list5frontEv@@GLIBCXX_3.4.31
>  FUNC:_ZNKSt6locale2id5_M_idEv@@GLIBCXX_3.4
>  FUNC:_ZNKSt6locale4nameB5cxx11Ev@@GLIBCXX_3.4.21
>  FUNC:_ZNKSt6locale4nameEv@@GLIBCXX_3.4
> @@ -3285,9 +3297,18 @@ 
> FUNC:_ZNSt6__norm15_List_node_base7_M_hookEPS0_@@GLIBCXX_3.4.14
>  FUNC:_ZNSt6__norm15_List_node_base7reverseEv@@GLIBCXX_3.4.9
>  FUNC:_ZNSt6__norm15_List_node_base8transferEPS0_S1_@@GLIBCXX_3.4.9
>  FUNC:_ZNSt6__norm15_List_node_base9_M_unhookEv@@GLIBCXX_3.4.14
> +FUNC:_ZNSt6chrono11locate_zoneESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.31
> +FUNC:_ZNSt6chrono11reload_tzdbEv@@GLIBCXX_3.4.31
> +FUNC:_ZNSt6chrono12current_zoneEv@@GLIBCXX_3.4.31
>  FUNC:_ZNSt6chrono12system_clock3nowEv@@GLIBCXX_3.4.11
> +FUNC:_ZNSt6chrono13get_tzdb_listEv@@GLIBCXX_3.4.31
> +FUNC:_ZNSt6chrono14remote_versionB5cxx11Ev@@GLIBCXX_3.4.31
>  FUNC:_ZNSt6chrono3_V212steady_clock3nowEv@@GLIBCXX_3.4.19
>  FUNC:_ZNSt6chrono3_V212system_clock3nowEv@@GLIBCXX_3.4.19
> +FUNC:_ZNSt6chrono8get_tzdbEv@@GLIBCXX_3.4.31
> +FUNC:_ZNSt6chrono9tzdb_list11erase_afterENS0_14const_iteratorE@@GLIBCXX_3.4.31
> +FUNC:_ZNSt6chrono9tzdb_list14const_iteratorppEi@@GLIBCXX_3.4.31
> +FUNC:_ZNSt6chrono9tzdb_list14const_iteratorppEv@@GLIBCXX_3.4.31
>  FUNC:_ZNSt6gslice8_IndexerC1EjRKSt8valarrayIjES4_@@GLIBCXX_3.4
>  FUNC:_ZNSt6gslice8_IndexerC2EjRKSt8valarrayIjES4_@@GLIBCXX_3.4
>  FUNC:_ZNSt6locale11_M_coalesceERKS_S1_i@@GLIBCXX_3.4
> @@ -3384,6 +3405,7 @@ 
> FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE10_M_disposeEv@@GLIBCX
>  
> FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE10_M_replaceEjjPKcj@@GLIBCXX_3.4.21
>  
> FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE10_S_compareEjj@@GLIBCXX_3.4.21
>  
> FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE11_M_capacityEj@@GLIBCXX_3.4.21
> +FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE11_S_allocateERS3_j@@GLIBCXX_3.4.32
>  
> FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_Alloc_hiderC1EPcOS3_@@GLIBCXX_3.4.23
>  
> FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_Alloc_hiderC1EPcRKS3_@@GLIBCXX_3.4.21
>  
> FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_Alloc_hiderC2EPcOS3_@@GLIBCXX_3.4.23
> @@ -3403,6 +3425,7 @@ 
> FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_S_copy_charsEPcPKcS
>  
> 

Re: Trait built-in naming convention

2024-05-02 Thread Jonathan Wakely
On Thu, 2 May 2024 at 18:38, Ville Voutilainen
 wrote:
>
> On Thu, 2 May 2024 at 20:25, Ken Matsui  wrote:
> > > There was some discussion of how to name the built-ins back in
> > > https://gcc.gnu.org/pipermail/gcc-patches/2007-March/thread.html#212171
> > > but __builtin wasn't discussed.
> > >
> > > Apparently this naming convention follows the MSVC precedent:
> > > http://msdn2.microsoft.com/en-us/library/ms177194.aspx
> > >
> > > I notice some discussion of this pattern around Clang adding various
> > > built-ins in https://github.com/llvm/llvm-project/issues/61852
> > > indicating that this is a policy based on precedent.
> > >
> > > But I don't see any actual reason for this pattern other than that it's
> > > what Paolo happened to do in 2007.
> > >
> > > I'm not sure what the right way forward is.  Perhaps we're stuck with
> > > the questionable choices of the past.
> > >
> >
> > Hmm, I personally prefer the __builtin prefix.  However, it seems that
> > we need to reach a consensus across MSVC, Clang, and GCC.  Would this
> > be realistically possible?
> >
> > Until then, I think it would be better to use __ for all built-in
> > traits.  What do you think?
>
> My 0.02: __builtin as a prefix doesn't serve much of a purpose.

The main advantage is that it avoids clashes with std::lib components
that previously used the __is_foo name and which need to be renamed to
support a built-in of that name.


[gcc r13-8675] libstdc++: Fix infinite loop in std::istream::ignore(n, delim) [PR93672]

2024-05-02 Thread Jonathan Wakely via Libstdc++-cvs
https://gcc.gnu.org/g:fcf60d0baafa1245f768ac375dc60a07e92e9673

commit r13-8675-gfcf60d0baafa1245f768ac375dc60a07e92e9673
Author: Jonathan Wakely 
Date:   Thu Apr 4 10:33:33 2024 +0100

libstdc++: Fix infinite loop in std::istream::ignore(n, delim) [PR93672]

A negative delim value passed to std::istream::ignore can never match
any character in the stream, because the comparison is done using
traits_type::eq_int_type(sb->sgetc(), delim) and sgetc() never returns
negative values (except at EOF). The optimized version of ignore for the
std::istream specialization uses traits_type::find to locate the delim
character in the streambuf, which _can_ match a negative delim on
platforms where char is signed, but then we do another comparison using
eq_int_type which fails. The code then keeps looping forever, with
traits_type::find locating the character and traits_type::eq_int_type
saying it's not a match, so traits_type::find is used again and finds
the same character again.

A possible fix would be to check with eq_int_type after a successful
find, to see whether we really have a match. However, that would be
suboptimal since we know that a negative delimiter will never match
using eq_int_type. So a better fix is to adjust the check at the top of
the function that handles delim==eof(), so that we treat all negative
delim values as equivalent to EOF. That way we don't bother using find
to search for something that will never match with eq_int_type.

The version of ignore in the primary template doesn't need a change,
because it doesn't use traits_type::find, instead characters are
extracted one-by-one and always matched using eq_int_type. That avoids
the inconsistency between find and eq_int_type. The specialization for
std::wistream does use traits_type::find, but traits_type::to_int_type
is equivalent to an implicit conversion from wchar_t to wint_t, so
passing a wchar_t directly to ignore without using to_int_type works.

libstdc++-v3/ChangeLog:

PR libstdc++/93672
* src/c++98/istream.cc (istream::ignore(streamsize, int_type)):
Treat all negative delimiter values as eof().
* testsuite/27_io/basic_istream/ignore/char/93672.cc: New test.
* testsuite/27_io/basic_istream/ignore/wchar_t/93672.cc: New
test.

(cherry picked from commit 2d694414ada8e3b58f504c1b175d31088529632e)

Diff:
---
 libstdc++-v3/src/c++98/istream.cc  |  13 ++-
 .../27_io/basic_istream/ignore/char/93672.cc   | 101 +
 .../27_io/basic_istream/ignore/wchar_t/93672.cc|  34 +++
 3 files changed, 146 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/src/c++98/istream.cc 
b/libstdc++-v3/src/c++98/istream.cc
index 74bf7b6f4fa..ebac7a6010b 100644
--- a/libstdc++-v3/src/c++98/istream.cc
+++ b/libstdc++-v3/src/c++98/istream.cc
@@ -112,8 +112,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 basic_istream::
 ignore(streamsize __n, int_type __delim)
 {
-  if (traits_type::eq_int_type(__delim, traits_type::eof()))
-   return ignore(__n);
+  {
+   // If conversion to int_type changes the value then __delim does not
+   // correspond to a value of type char_type, and so will never match
+   // a character extracted from the input sequence. Just use ignore(n).
+   const int_type chk_delim = traits_type::to_int_type(__delim);
+   const bool matchable = traits_type::eq_int_type(chk_delim, __delim);
+   if (__builtin_expect(!matchable, 0))
+ return ignore(__n);
+   // Now we know that __delim is a valid char_type value, so it's safe
+   // for the code below to use traits_type::find to search for it.
+  }
 
   _M_gcount = 0;
   sentry __cerb(*this, true);
diff --git a/libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/93672.cc 
b/libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/93672.cc
new file mode 100644
index 000..96737485b83
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_istream/ignore/char/93672.cc
@@ -0,0 +1,101 @@
+// { dg-do run }
+
+#include 
+#include 
+#include 
+
+void
+test_pr93672() // std::basic_istream::ignore hangs if delim MSB is set
+{
+  std::istringstream in(".\xfc..\xfd...\xfe.");
+
+  // This should find '\xfd' even on platforms where char is signed,
+  // because the delimiter is correctly converted to the stream's int_type.
+  in.ignore(100, std::char_traits::to_int_type('\xfc'));
+  VERIFY( in.gcount() == 2 );
+  VERIFY( ! in.eof() );
+
+  // This should work equivalently to traits_type::to_int_type
+  in.ignore(100, (unsigned char)'\xfd');
+  VERIFY( in.gcount() == 3 );
+  VERIFY( ! in.eof() );
+
+  // This only works if char is unsigned.
+  in.ignore(100, '\xfe');
+  if (std::numeric_limits::is_signed)
+  {
+// When char is signed, '\xfe' != traits_type::to_int_type('\xfe

[gcc r13-8674] libstdc++: Reverse arguments in constraint for std::optional's <=> [PR104606]

2024-05-02 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:3d16f8f2aec9583422d00c531732ca9d33e6ef26

commit r13-8674-g3d16f8f2aec9583422d00c531732ca9d33e6ef26
Author: Jonathan Wakely 
Date:   Wed Mar 27 21:51:13 2024 +

libstdc++: Reverse arguments in constraint for std::optional's <=> 
[PR104606]

This is a workaround for a possible compiler bug that causes constraint
recursion in the operator<=>(const optional&, const U&) overload.

libstdc++-v3/ChangeLog:

PR libstdc++/104606
* include/std/optional (operator<=>(const optional&, const U&)):
Reverse order of three_way_comparable_with template arguments.
* testsuite/20_util/optional/relops/104606.cc: New test.

(cherry picked from commit 7f65d8267fbfd19cf21a3dc71d27e989e75044a3)

Diff:
---
 libstdc++-v3/include/std/optional  |  2 +-
 .../testsuite/20_util/optional/relops/104606.cc| 18 ++
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/optional 
b/libstdc++-v3/include/std/optional
index 29f534b9861..e4f3fc65340 100644
--- a/libstdc++-v3/include/std/optional
+++ b/libstdc++-v3/include/std/optional
@@ -1434,7 +1434,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #ifdef __cpp_lib_three_way_comparison
   template
 requires (!__is_optional_v<_Up>)
-  && three_way_comparable_with<_Tp, _Up>
+  && three_way_comparable_with<_Up, _Tp>
 constexpr compare_three_way_result_t<_Tp, _Up>
 operator<=>(const optional<_Tp>& __x, const _Up& __v)
 { return bool(__x) ? *__x <=> __v : strong_ordering::less; }
diff --git a/libstdc++-v3/testsuite/20_util/optional/relops/104606.cc 
b/libstdc++-v3/testsuite/20_util/optional/relops/104606.cc
new file mode 100644
index 000..2b8df245219
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/optional/relops/104606.cc
@@ -0,0 +1,18 @@
+// { dg-do compile { target c++17 } }
+
+// Bug 104606 comparison operator resolution with std::optional and -std=c++20
+
+#include 
+#include 
+#include 
+
+struct Value : std::variant> { };
+
+struct Comparator {
+  template  bool operator<=(const T &) { return true; }
+};
+
+std::optional o;
+Comparator c;
+
+auto x = c <= o;


[PATCH] libstdc++: Fix for -std=c++23 -ffreestanding [PR114866]

2024-05-02 Thread Jonathan Wakely
Tested x86_64-linux.

It would also be possible to fix this with:

#if ! _GLIBCXX_HOSTED
  template inline constexpr __is_shared_ptr = false;
#endif

But we would still need to guard the partial specializations that use
shared_ptr and __shared_ptr. It seemed cleaner to just guard all uses of
anything related to shared_ptr so it all goes away for freestanding.

While working on this I noticed that when I added __is_shared_ptr I made
it 'static constexpr' for some reason, rather than 'inline constexpr'.
I'll change that separately.

-- >8 --

std::shared_ptr isn't declared for freestanding, so guard uses of it
with #if _GLIBCXX_HOSTED in .

libstdc++-v3/ChangeLog:

PR libstdc++/114866
* include/bits/out_ptr.h [!_GLIBCXX_HOSTED]: Don't refer to
shared_ptr, __shared_ptr or __is_shred_ptr.
* testsuite/20_util/headers/memory/114866.cc: New test.
---
 libstdc++-v3/include/bits/out_ptr.h| 10 ++
 .../testsuite/20_util/headers/memory/114866.cc |  4 
 2 files changed, 14 insertions(+)
 create mode 100644 libstdc++-v3/testsuite/20_util/headers/memory/114866.cc

diff --git a/libstdc++-v3/include/bits/out_ptr.h 
b/libstdc++-v3/include/bits/out_ptr.h
index aeeb6640441..d74c9f52d3b 100644
--- a/libstdc++-v3/include/bits/out_ptr.h
+++ b/libstdc++-v3/include/bits/out_ptr.h
@@ -54,9 +54,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 class out_ptr_t
 {
+#if _GLIBCXX_HOSTED
   static_assert(!__is_shared_ptr<_Smart> || sizeof...(_Args) != 0,
"a deleter must be used when adapting std::shared_ptr "
"with std::out_ptr");
+#endif
 
 public:
   explicit
@@ -216,6 +218,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  [[no_unique_address]] _Del2 _M_del;
};
 
+#if _GLIBCXX_HOSTED
   // Partial specialization for std::shared_ptr.
   // This specialization gives direct access to the private member
   // of the shared_ptr, avoiding the overhead of storing a separate
@@ -274,6 +277,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
  using _Impl<_Smart, _Pointer, _Del, allocator>::_Impl;
};
+#endif
 
   using _Impl_t = _Impl<_Smart, _Pointer, _Args...>;
 
@@ -293,8 +297,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 class inout_ptr_t
 {
+#if _GLIBCXX_HOSTED
   static_assert(!__is_shared_ptr<_Smart>,
"std::inout_ptr can not be used to wrap std::shared_ptr");
+#endif
 
 public:
   explicit
@@ -320,11 +326,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   }
 
 private:
+#if _GLIBCXX_HOSTED
   // Avoid an invalid instantiation of out_ptr_t, ...>
   using _Out_ptr_t
= __conditional_t<__is_shared_ptr<_Smart>,
  out_ptr_t,
  out_ptr_t<_Smart, _Pointer, _Args...>>;
+#else
+  using _Out_ptr_t = out_ptr_t<_Smart, _Pointer, _Args...>;
+#endif
   using _Impl_t = typename _Out_ptr_t::_Impl_t;
   _Impl_t _M_impl;
 };
diff --git a/libstdc++-v3/testsuite/20_util/headers/memory/114866.cc 
b/libstdc++-v3/testsuite/20_util/headers/memory/114866.cc
new file mode 100644
index 000..7cf6be0539d
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/headers/memory/114866.cc
@@ -0,0 +1,4 @@
+// { dg-options "-ffreestanding" }
+// { dg-do compile }
+// PR libstdc++/114866  & out_ptr in freestanding
+#include 
-- 
2.44.0



Re: [PATCH] libstdc++: Fix std::chrono::tzdb to work with vanguard format

2024-05-02 Thread Jonathan Wakely
On Thu, 2 May 2024 at 12:24, Jonathan Wakely  wrote:
>
> I found some issues in the std::chrono::tzdb parser by testing the
> tzdata "vanguard" format, which uses new features that aren't enabled in
> the "main" and "rearguard" data formats.
>
> Since 2024a the keyword "minimum" is no longer valid for the FROM and TO
> fields in a Rule line, which means that "m" is now a valid abbreviation
> for "maximum". Previously we expected either "mi" or "ma". For backwards
> compatibility, a FROM field beginning with "mi" is still supported and
> is treated as 1900. The "maximum" keyword is only allowed in TO now,
> because it makes no sense in FROM. To support these changes the
> minmax_year and minmax_year2 classes for parsing FROM and TO are
> replaced with a single years_from_to class that reads both fields.
>
> The vanguard format makes use of %z in Zone FORMAT fields, which caused
> an exception to be thrown from ZoneInfo::set_abbrev because no % or /
> characters were expected when a Zone doesn't use a named Rule. The
> ZoneInfo::to(sys_info&) function now uses format_abbrev_str to replace
> any %z with the current offset. Although format_abbrev_str also checks
> for %s and STD/DST formats, those only make sense when a named Rule is
> in effect, so won't occur when ZoneInfo::to(sys_info&) is used.
>
> This change also implements a feature that has always been missing from
> time_zone::_M_get_sys_info: finding the Rule that is active before the
> specified time point, so that we can correctly handle %s in the FORMAT
> for the first new sys_info that gets created. This requires implementing
> a poorly documented feature of zic, to get the LETTERS field from a
> later transition, as described at
> https://mm.icann.org/pipermail/tz/2024-April/058891.html
> In order for this to work we need to be able to distinguish an empty
> letters field (as used by CE%sT where the variable part is either empty
> or "S") from "the letters field is not known for this transition". The
> tzdata file uses "-" for an empty letters field, which libstdc++ was
> previously replacing with "" when the Rule was parsed. Instead, we now
> preserve the "-" in the Rule object, so that "" can be used for the case
> where we don't know the letters (and so need to decide it).
>
> libstdc++-v3/ChangeLog:
>
> * src/c++20/tzdb.cc (minmax_year, minmax_year2): Remove.
> (years_from_to): New class replacing minmax_year and
> minmax_year2.
> (format_abbrev_str, select_std_or_dst_abbrev): Move earlier in
> the file. Handle "-" for letters.
> (ZoneInfo::to): Use format_abbrev_str to expand %z.
> (ZoneInfo::set_abbrev): Remove exception. Change parameter from
> reference to value.
> (operator>>(istream&, Rule&)): Do not clear letters when it
> contains "-".
> (time_zone::_M_get_sys_info): Add missing logic to find the Rule
> in effect before the time point.
> * testsuite/std/time/tzdb/1.cc: Adjust for vanguard format using
> "GMT" as the Zone name, not as a Link to "Etc/GMT".
> * testsuite/std/time/time_zone/sys_info_abbrev.cc: New test.
> ---
>  libstdc++-v3/src/c++20/tzdb.cc| 265 +++---
>  .../std/time/time_zone/sys_info_abbrev.cc | 106 +++
>  libstdc++-v3/testsuite/std/time/tzdb/1.cc |   6 +-
>  3 files changed, 274 insertions(+), 103 deletions(-)
>  create mode 100644 
> libstdc++-v3/testsuite/std/time/time_zone/sys_info_abbrev.cc
>
> diff --git a/libstdc++-v3/src/c++20/tzdb.cc b/libstdc++-v3/src/c++20/tzdb.cc
> index c7c7cc9deee..32a3a92075d 100644
> --- a/libstdc++-v3/src/c++20/tzdb.cc
> +++ b/libstdc++-v3/src/c++20/tzdb.cc

[...]

> @@ -557,7 +605,7 @@ namespace std::chrono
> if (save_time.indicator != at_time::Wall)
>   {
> // We don't actually store the save_time.indicator, because we
> -   // assume that it's always deducable from the actual offset value.
> +   // assume that it's always deducable from the offset value.

That should be "deducible", I've fixed that locally.



[PATCH] libstdc++: Fix std::chrono::tzdb to work with vanguard format

2024-05-02 Thread Jonathan Wakely
I found some issues in the std::chrono::tzdb parser by testing the
tzdata "vanguard" format, which uses new features that aren't enabled in
the "main" and "rearguard" data formats.

Since 2024a the keyword "minimum" is no longer valid for the FROM and TO
fields in a Rule line, which means that "m" is now a valid abbreviation
for "maximum". Previously we expected either "mi" or "ma". For backwards
compatibility, a FROM field beginning with "mi" is still supported and
is treated as 1900. The "maximum" keyword is only allowed in TO now,
because it makes no sense in FROM. To support these changes the
minmax_year and minmax_year2 classes for parsing FROM and TO are
replaced with a single years_from_to class that reads both fields.

The vanguard format makes use of %z in Zone FORMAT fields, which caused
an exception to be thrown from ZoneInfo::set_abbrev because no % or /
characters were expected when a Zone doesn't use a named Rule. The
ZoneInfo::to(sys_info&) function now uses format_abbrev_str to replace
any %z with the current offset. Although format_abbrev_str also checks
for %s and STD/DST formats, those only make sense when a named Rule is
in effect, so won't occur when ZoneInfo::to(sys_info&) is used.

This change also implements a feature that has always been missing from
time_zone::_M_get_sys_info: finding the Rule that is active before the
specified time point, so that we can correctly handle %s in the FORMAT
for the first new sys_info that gets created. This requires implementing
a poorly documented feature of zic, to get the LETTERS field from a
later transition, as described at
https://mm.icann.org/pipermail/tz/2024-April/058891.html
In order for this to work we need to be able to distinguish an empty
letters field (as used by CE%sT where the variable part is either empty
or "S") from "the letters field is not known for this transition". The
tzdata file uses "-" for an empty letters field, which libstdc++ was
previously replacing with "" when the Rule was parsed. Instead, we now
preserve the "-" in the Rule object, so that "" can be used for the case
where we don't know the letters (and so need to decide it).

libstdc++-v3/ChangeLog:

* src/c++20/tzdb.cc (minmax_year, minmax_year2): Remove.
(years_from_to): New class replacing minmax_year and
minmax_year2.
(format_abbrev_str, select_std_or_dst_abbrev): Move earlier in
the file. Handle "-" for letters.
(ZoneInfo::to): Use format_abbrev_str to expand %z.
(ZoneInfo::set_abbrev): Remove exception. Change parameter from
reference to value.
(operator>>(istream&, Rule&)): Do not clear letters when it
contains "-".
(time_zone::_M_get_sys_info): Add missing logic to find the Rule
in effect before the time point.
* testsuite/std/time/tzdb/1.cc: Adjust for vanguard format using
"GMT" as the Zone name, not as a Link to "Etc/GMT".
* testsuite/std/time/time_zone/sys_info_abbrev.cc: New test.
---
 libstdc++-v3/src/c++20/tzdb.cc| 265 +++---
 .../std/time/time_zone/sys_info_abbrev.cc | 106 +++
 libstdc++-v3/testsuite/std/time/tzdb/1.cc |   6 +-
 3 files changed, 274 insertions(+), 103 deletions(-)
 create mode 100644 libstdc++-v3/testsuite/std/time/time_zone/sys_info_abbrev.cc

diff --git a/libstdc++-v3/src/c++20/tzdb.cc b/libstdc++-v3/src/c++20/tzdb.cc
index c7c7cc9deee..32a3a92075d 100644
--- a/libstdc++-v3/src/c++20/tzdb.cc
+++ b/libstdc++-v3/src/c++20/tzdb.cc
@@ -342,51 +342,103 @@ namespace std::chrono
   friend istream& operator>>(istream&, on_day&);
 };
 
-// Wrapper for chrono::year that reads a year, or one of the keywords
-// "minimum" or "maximum", or an unambiguous prefix of a keyword.
-struct minmax_year
+// Wrapper for two chrono::year values, which reads the FROM and TO
+// fields of a Rule line. The FROM field is a year and TO is a year or
+// one of the keywords "maximum" or "only" (or an abbreviation of those).
+// For backwards compatibility, the keyword "minimum" is recognized
+// for FROM and interpreted as 1900.
+struct years_from_to
 {
-  year& y;
+  year& from;
+  year& to;
 
-  friend istream& operator>>(istream& in, minmax_year&& y)
+  friend istream& operator>>(istream& in, years_from_to&& yy)
   {
-   if (ws(in).peek() == 'm') // keywords "minimum" or "maximum"
+   string s;
+   auto c = ws(in).peek();
+   if (c == 'm') [[unlikely]] // keyword "minimum"
  {
-   string s;
-   in >> s; // extract the rest of the word, but only look at s[1]
-   if (s[1] == 'a')
- y.y = year::max();
-   else if (s[1] == 'i')
- y.y = year::min();
-   else
- in.setstate(ios::failbit);
+   in >> s; // extract the rest of the word
+   yy.from = year(1900);
+ }
+   else if (int num = 0; in >> num) [[likely]]

[gcc r11-11411] libstdc++: Add missing std::tuple constructor [PR114147]

2024-05-02 Thread Jonathan Wakely via Gcc-cvs
https://gcc.gnu.org/g:0ecb0967b4f7e68027492ac03e5dc03b5bcfdcf7

commit r11-11411-g0ecb0967b4f7e68027492ac03e5dc03b5bcfdcf7
Author: Jonathan Wakely 
Date:   Fri Mar 1 11:16:58 2024 +

libstdc++: Add missing std::tuple constructor [PR114147]

I caused a regression with commit r10-908 by adding a constraint to the
non-explicit allocator-extended default constructor, but seemingly
forgot to add an explicit overload with the corresponding constraint.

libstdc++-v3/ChangeLog:

PR libstdc++/114147
* include/std/tuple (tuple::tuple(allocator_arg_t, const Alloc&)):
Add missing overload of allocator-extended default constructor.
(tuple::tuple(allocator_arg_t, const Alloc&)): Likewise.
* testsuite/20_util/tuple/cons/114147.cc: New test.

(cherry picked from commit 0a545ac7000501844670add0b3560ebdbcb123c6)

Diff:
---
 libstdc++-v3/include/std/tuple  | 14 ++
 libstdc++-v3/testsuite/20_util/tuple/cons/114147.cc | 15 +++
 2 files changed, 29 insertions(+)

diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index 63bd68fbe43..b02b0bfbd59 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -801,6 +801,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
tuple(allocator_arg_t __tag, const _Alloc& __a)
: _Inherited(__tag, __a) { }
 
+  template::value> = false>
+   _GLIBCXX20_CONSTEXPR
+   explicit
+   tuple(allocator_arg_t __tag, const _Alloc& __a)
+   : _Inherited(__tag, __a) { }
+
   template= 1),
   _ImplicitCtor<_NotEmpty, const _Elements&...> = true>
_GLIBCXX20_CONSTEXPR
@@ -1155,6 +1162,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
tuple(allocator_arg_t __tag, const _Alloc& __a)
: _Inherited(__tag, __a) { }
 
+  template::value, _T1, _T2> = false>
+   _GLIBCXX20_CONSTEXPR
+   explicit
+   tuple(allocator_arg_t __tag, const _Alloc& __a)
+   : _Inherited(__tag, __a) { }
+
   template = true>
_GLIBCXX20_CONSTEXPR
diff --git a/libstdc++-v3/testsuite/20_util/tuple/cons/114147.cc 
b/libstdc++-v3/testsuite/20_util/tuple/cons/114147.cc
new file mode 100644
index 000..916e7204964
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/tuple/cons/114147.cc
@@ -0,0 +1,15 @@
+// { dg-do compile { target c++11 } }
+
+// PR libstdc++/114147
+// tuple allocator-extended ctor requires non-explicit default ctor
+
+#include 
+#include 
+
+struct X { explicit X(); };
+
+std::allocator a;
+std::tuple t0(std::allocator_arg, a);
+std::tuple t1(std::allocator_arg, a);
+std::tuple t2(std::allocator_arg, a);
+std::tuple t3(std::allocator_arg, a);


  1   2   3   4   5   6   7   8   9   10   >