Re: [PATCH] libstdc++: Add masked ++/-- implementation for sizeof < 16

2024-03-27 Thread Jonathan Wakely
On Wed, 27 Mar 2024 at 12:48, Matthias Kretz  wrote:
>
> And one more to fix follow-up / remaining failures. Tested on x86_64-linux-
> gnu.
>
> OK for trunk and 13?

OK for both, thanks.


>
>  8< --
>
> This resolves further failures (-Wreturn-type warnings) and test
> failures for where-* tests targeting AVX-512.
>
> Signed-off-by: Matthias Kretz 
>
> libstdc++-v3/ChangeLog:
>
> * include/experimental/bits/simd_x86.h (_S_masked_unary):
> Cast inputs < 16 bytes to 16 byte vectors before calling the
> right subtraction builtin. Before returning, truncate to the
> return vector type.
> ---
>  .../include/experimental/bits/simd_x86.h  | 24 +++
>  1 file changed, 14 insertions(+), 10 deletions(-)
>
>
> --
> ──
>  Dr. Matthias Kretz   https://mattkretz.github.io
>  GSI Helmholtz Centre for Heavy Ion Research   https://gsi.de
>  stdₓ::simd
> ──


Re: [PATCH v2] libstdc++: add ARM SVE support to std::experimental::simd

2024-03-27 Thread Jonathan Wakely
On Wed, 27 Mar 2024 at 12:13, Richard Sandiford
 wrote:
>
> Matthias Kretz  writes:
> > On Wednesday, 27 March 2024 11:07:14 CET Richard Sandiford wrote:
> >> I'm still worried about:
> >>
> >>   #if _GLIBCXX_SIMD_HAVE_SVE
> >>   constexpr inline int __sve_vectorized_size_bytes = __ARM_FEATURE_SVE_BITS
> >> / 8; #else
> >>   constexpr inline int __sve_vectorized_size_bytes = 0;
> >>   #endif
> >>
> >> and the direct use __ARM_FEATURE_SVE_BITS elsewhere, for the reasons
> >> discussed here (including possible ODR problems):
> >>
> >>   https://gcc.gnu.org/pipermail/gcc-patches/2023-December/640037.html
> >>   https://gcc.gnu.org/pipermail/gcc-patches/2024-January/643734.html
> >>
> >> Logically the vector length should be a template parameter rather than
> >> an invariant.  Has this been resolved?  If not, it feels like a blocker
> >> to me (sorry).
> >
> > The vector length is always a template parameter to all user-facing API. 
> > Some
> > examples
> >
> > 1. on aarch64 the following is independent of SVE flags (and status quo):
> >
> >   simd is an alias for
> >   simd
> >
> >   fixed_size_simd is supposed to be ABI-stable anyway (passed via
> >   the stack, alignof == sizeof).
> >
> > 2. with -msve-vector-bits=512:
> >
> >   native_simd is an alias for
> >   simd>
> >
> >   simd> is an alias for
> >   simd>
> >
> > 3. with -msve-vector-bits=256:
> >
> >   native_simd is an alias for
> >   simd>
> >
> >   simd> is an alias for
> >   simd>
> >
> > Implementation functions are either [[gnu::always_inline]] or tagged with 
> > the
> > ABI tag type and the __odr_helper template argument (to ensure not-inlined
> > inline functions have unique names).
>
> Ah, thanks for the explanation.  I think the global native_float alias
> is problematic for reasons that you touched on in your later message.
> I'll reply more about that there.  But in other respects this looks good.
>
> > Does that make __ARM_FEATURE_SVE_BITS usage indirect enough?
>
> In principle, the only use of __ARM_FEATURE_SVE_BITS should be to determine
> the definition of native_simd (with the caveats above).  But current
> GCC restrictions might make that impractical.
>
> > Also for context, please consider that this is std::*experimental*::simd. 
> > The
> > underlying ISO document will likely get retracted at some point and the 
> > whole
> > API and implementation (hopefully) superseded by C++26. The main purpose of
> > the spec and implementation is to gather experience.
>
> Ah, ok.  If this is a deliberate experiment for evidence-gathering
> purposes, rather than a long-term commitment, then I agree the barrier
> should be lower.

Yes, that's definitely what this code is for. The more feedback and
impl-experience we can get now with the std::experimental::simd
version, the better std::simd will be when that happens.

In practice, we probably won't ever actually remove the
 header even when the experiment is over (e.g. we
still have  with std::tr1::shared_ptr!), but we are likely
to consider it unmaintained and deprecated once it's superseded by
std::simd.

> So yeah, I'll withdraw my objection.  I've no problem with this going
> into GCC 14 on the basis above.  Thanks again to you and Srinivas for
> working on this.
>
> Richard
>



Re: [PATCH v2] libstdc++: add ARM SVE support to std::experimental::simd

2024-03-27 Thread Jonathan Wakely
On Fri, 8 Mar 2024 at 09:58, Matthias Kretz wrote:
>
> Hi,
>
> I applied and did extended testing on x86_64 (no regressions) and aarch64
> using qemu testing SVE 256, 512, and 1024. Looks good!
>
> While going through the applied patch I noticed a few style issues that I
> simply turned into a patch (attached).
>
[...]
>
> From my side, with the noted changes the patch is ready for merging.
> @Jonathan, any chance for a green light before GCC 14.1?

As discussed on IRC, please push the revised patch with your
suggestions incorporated (and post to the lists for posterity).

Thanks, everybody, for the patches and the thorough review.



Re: [PATCH] libstdc++: Fix call signature of builtins from masked ++/--

2024-03-27 Thread Jonathan Wakely
On Wed, 27 Mar 2024 at 08:51, Matthias Kretz  wrote:
>
> This is broken on GCC 13 and 14 (https://compiler-explorer.com/z/GPKGPGs6T)
>
> Tested on x86_64-linux-gnu.
>
> OK for trunk and 13?

OK for both, thanks.


>
> --- 8< -
>
> This resolves failures in the "expensive" where-* test of check-simd
> when targeting AVX-512.
>
> Signed-off-by: Matthias Kretz 
>
> libstdc++-v3/ChangeLog:
>
> * include/experimental/bits/simd_x86.h (_S_masked_unary): Call
> the 4- and 8-byte variants of __builtin_ia32_subp[ds] without
> rounding direction argument.
> ---
>  libstdc++-v3/include/experimental/bits/simd_x86.h | 12 +---
>  1 file changed, 9 insertions(+), 3 deletions(-)
>
>
> --
> ──
>  Dr. Matthias Kretz   https://mattkretz.github.io
>  GSI Helmholtz Centre for Heavy Ion Research   https://gsi.de
>  stdₓ::simd
> ──


Re: [PATCH 1/2] libstdc++: Add dg-require-cpp-feature-test to test feature test macros

2024-03-26 Thread Jonathan Wakely
Pushed to trunk.

On Sat, 23 Mar 2024 at 00:22, Jonathan Wakely  wrote:
>
> Thoughts? There are only a few uses for this presently, but I can see it
> being useful often in future. The library exposes which features it
> supports in a standardized way, so we can use those in tests to skip
> tests for features that aren't available on all targets.
>
> The obvious downside is that it becomes harder to notice if a particular
> feature is missing on all targets, because we don't get FAILs we just
> skip all tests as UNSUPPORTED. And the checks for whether 
> correctly defines the macro become redundant, because the test won't
> even get run if it doesn't. But we won't use this dg-require for many
> tests, only the ones where support is target-dependent because it relies
> on something non-standard or not available on all targets (like
> nl_langinfo_l or libbacktrace).
>
> -- >8 -
>
> This adds a new dejagnu directive which can be used to make a test
> depend on a feature test macro such as __cpp_lib_text_encoding. This is
> mroe flexible than writing a new dg-require-xxx for each feature.
>
> libstdc++-v3/ChangeLog:
>
> * testsuite/lib/dg-options.exp (dg-require-cpp-feature-test):
> New proc.
> * testsuite/lib/libstdc++.exp (check_v3_target_cpp_feature_test):
> New proc.
> * testsuite/std/text_encoding/cons.cc: Use new directive to skip
> the test if the __cpp_lib_text_encoding feature test macro is
> not defined.
> * testsuite/std/text_encoding/requirements.cc: Likewise.
> ---
>  libstdc++-v3/testsuite/lib/dg-options.exp |  9 +
>  libstdc++-v3/testsuite/lib/libstdc++.exp  | 15 +++
>  libstdc++-v3/testsuite/std/text_encoding/cons.cc  |  1 +
>  .../testsuite/std/text_encoding/requirements.cc   |  3 ++-
>  4 files changed, 27 insertions(+), 1 deletion(-)
>
> diff --git a/libstdc++-v3/testsuite/lib/dg-options.exp 
> b/libstdc++-v3/testsuite/lib/dg-options.exp
> index 00ca678a53a..802bfc0b492 100644
> --- a/libstdc++-v3/testsuite/lib/dg-options.exp
> +++ b/libstdc++-v3/testsuite/lib/dg-options.exp
> @@ -277,6 +277,15 @@ proc dg-require-target-fs-lwt { args } {
>  return
>  }
>
> +proc dg-require-cpp-feature-test { n args } {
> +if { ![ check_v3_target_cpp_feature_test $args ] } {
> +   upvar dg-do-what dg-do-what
> +   set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"]
> +   return
> +}
> +return
> +}
> +
>  proc add_options_for_no_pch { flags } {
>  # Remove any inclusion of bits/stdc++.h from the options.
>  regsub -all -- "-include bits/stdc...h" $flags "" flags
> diff --git a/libstdc++-v3/testsuite/lib/libstdc++.exp 
> b/libstdc++-v3/testsuite/lib/libstdc++.exp
> index 7466fb51c58..2b31c950826 100644
> --- a/libstdc++-v3/testsuite/lib/libstdc++.exp
> +++ b/libstdc++-v3/testsuite/lib/libstdc++.exp
> @@ -1134,6 +1134,21 @@ proc v3_check_preprocessor_condition { name cond { inc 
> "" } } {
>  return [v3_try_preprocess name $code $flags]
>  }
>
> +# Return 1 if libstdc++ defines macro for the current target, 0 otherwise.
> +proc check_v3_target_cpp_feature_test { cond } {
> +global cxxflags
> +set cxxflags_saved $cxxflags
> +# Use the latest standard, so that all feature test macros are defined.
> +# We need to do it here, because this check happens before v3-dg-runtest
> +# runs its loop to test multiple times with different -std options.
> +# This should be updated when a new -std is added.
> +set cxxflags "$cxxflags -std=gnu++26"
> +set inc "#include "
> +set result [v3_check_preprocessor_condition cpp_feature_test "$cond" 
> $inc]
> +set cxxflags $cxxflags_saved
> +return $result
> +}
> +
>  # Return 1 if Debug Mode is active, 0 otherwise.
>  proc check_v3_target_debug_mode { } {
>  global cxxflags
> diff --git a/libstdc++-v3/testsuite/std/text_encoding/cons.cc 
> b/libstdc++-v3/testsuite/std/text_encoding/cons.cc
> index 8fcc2ec8c3b..4196e32ea8b 100644
> --- a/libstdc++-v3/testsuite/std/text_encoding/cons.cc
> +++ b/libstdc++-v3/testsuite/std/text_encoding/cons.cc
> @@ -1,4 +1,5 @@
>  // { dg-do run { target c++26 } }
> +// { dg-require-cpp-feature-test "__cpp_lib_text_encoding" }
>
>  #include 
>  #include 
> diff --git a/libstdc++-v3/testsuite/std/text_encoding/requirements.cc 
> b/libstdc++-v3/testsuite/std/text_encoding/requirements.cc
> index a1d5d6baee1..3889b250688 100644
> --- a/libstdc++-v3/testsuite/std/text_encoding/requirements.cc
> +++ b/libstdc++-v3/testsuite/std/text_encoding/requirements.cc
> @@ -1,4 +1,5 @@
>  // { dg-do compile { target c++26 } }
> +// { dg-require-cpp-feature-test __cpp_lib_text_encoding }
>  // { dg-add-options no_pch }
>
>  #include 
>



Re: [PATCH 2/2] libstdc++: Replace stacktrace effective target with feature test

2024-03-26 Thread Jonathan Wakely
Pushed to trunk.

On Sat, 23 Mar 2024 at 00:22, Jonathan Wakely  wrote:
>
> And this replaces an existing custom dg-require- directive with a use of
> the new one that checks for a standard feature test macro. I didn't see
> any other existing dg-require-xxx directives that can be replaced like
> this.
>
> -- >8 --
>
> Remove the dejagnu code for checking whether std::stacktrace is supported
> and just use the new dg-require-cpp-feature-test directive to check for
> __cpp_lib_stacktrace instead.
>
> libstdc++-v3/ChangeLog:
>
> * testsuite/19_diagnostics/stacktrace/current.cc: Check for
> __cpp_lib_stacktrace instead of check for stacktrace ET.
> * 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.
> * testsuite/19_diagnostics/stacktrace/synopsis.cc: Likewise.
> * testsuite/19_diagnostics/stacktrace/version.cc: Likewise.
> * testsuite/23_containers/vector/debug/assign4_backtrace_neg.cc:
> Likewise.
> * testsuite/lib/libstdc++.exp (check_effective_target_stacktrace):
> Remove.
> ---
>  .../testsuite/19_diagnostics/stacktrace/current.cc| 2 +-
>  libstdc++-v3/testsuite/19_diagnostics/stacktrace/entry.cc | 2 +-
>  libstdc++-v3/testsuite/19_diagnostics/stacktrace/hash.cc  | 2 +-
>  .../testsuite/19_diagnostics/stacktrace/output.cc | 2 +-
>  .../testsuite/19_diagnostics/stacktrace/stacktrace.cc | 2 +-
>  .../testsuite/19_diagnostics/stacktrace/synopsis.cc   | 2 +-
>  .../testsuite/19_diagnostics/stacktrace/version.cc| 2 +-
>  .../23_containers/vector/debug/assign4_backtrace_neg.cc   | 2 +-
>  libstdc++-v3/testsuite/lib/libstdc++.exp  | 8 
>  9 files changed, 8 insertions(+), 16 deletions(-)
>
> diff --git a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/current.cc 
> b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/current.cc
> index a27836d27af..b1af5f74fb2 100644
> --- a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/current.cc
> +++ b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/current.cc
> @@ -1,6 +1,6 @@
>  // { dg-options "-lstdc++exp" }
>  // { dg-do run { target c++23 } }
> -// { dg-require-effective-target stacktrace }
> +// { dg-require-cpp-feature-test __cpp_lib_stacktrace }
>
>  #include 
>  #include 
> diff --git a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/entry.cc 
> b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/entry.cc
> index ab016d56400..bb348ebef8f 100644
> --- a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/entry.cc
> +++ b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/entry.cc
> @@ -1,6 +1,6 @@
>  // { dg-options "-lstdc++exp" }
>  // { dg-do run { target c++23 } }
> -// { dg-require-effective-target stacktrace }
> +// { dg-require-cpp-feature-test __cpp_lib_stacktrace }
>
>  #include 
>  #include "testsuite_hooks.h"
> diff --git a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/hash.cc 
> b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/hash.cc
> index 21705098ff0..2176596ae5c 100644
> --- a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/hash.cc
> +++ b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/hash.cc
> @@ -1,6 +1,6 @@
>  // { dg-options "-lstdc++exp" }
>  // { dg-do run { target c++23 } }
> -// { dg-require-effective-target stacktrace }
> +// { dg-require-cpp-feature-test __cpp_lib_stacktrace }
>
>  #include 
>  #include 
> diff --git a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/output.cc 
> b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/output.cc
> index 67f1e0cebaf..e27aea1f508 100644
> --- a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/output.cc
> +++ b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/output.cc
> @@ -1,6 +1,6 @@
>  // { dg-options "-lstdc++exp" }
>  // { dg-do run { target c++23 } }
> -// { dg-require-effective-target stacktrace }
> +// { dg-require-cpp-feature-test __cpp_lib_stacktrace }
>  // { dg-add-options no_pch }
>
>  #include 
> diff --git a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc 
> b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc
> index 5dfa76951df..070c4157471 100644
> --- a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc
> +++ b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc
> @@ -1,6 +1,6 @@
>  // { dg-options "-lstdc++exp" }
>  // { dg-do run { target c++23 } }
> -// { dg-require-effective-target stacktrace }
> +// { dg-require-cpp-featu

Re: [PATCH 1/2] libstdc++: fix _V badname in

2024-03-26 Thread Jonathan Wakely
On Sat, 23 Mar 2024 at 15:47, Arsen Arsenović wrote:
>
> libstdc++-v3/ChangeLog:
>
> * include/std/generator: Fix _V badname.

OK for trunk, thanks.


> ---
>  libstdc++-v3/include/std/generator | 18 ++
>  1 file changed, 10 insertions(+), 8 deletions(-)
>
> diff --git a/libstdc++-v3/include/std/generator 
> b/libstdc++-v3/include/std/generator
> index 87983ee5e7c6..2d1dcced1e57 100644
> --- a/libstdc++-v3/include/std/generator
> +++ b/libstdc++-v3/include/std/generator
> @@ -76,14 +76,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> * @headerfile generator
> * @since C++23
> */
> -  template
> +  template
>  class generator;
>
>/// @cond undocumented
>namespace __gen
>{
>  /// _Reference type for a generator whose reference (first argument) and
> -/// value (second argument) types are _Ref and _V.
> +/// value (second argument) types are _Ref and _Val.
>  template
>  using _Reference_t = __conditional_t,
>  _Ref&&, _Ref>;
> @@ -642,14 +642,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>} // namespace __gen
>/// @endcond
>
> -  template
> +  template
>  class generator
> -  : public ranges::view_interface>
> +  : public ranges::view_interface>
>  {
> -  using _Value = __conditional_t, remove_cvref_t<_Ref>, 
> _V>;
> +  using _Value = __conditional_t,
> +remove_cvref_t<_Ref>,
> +_Val>;
>static_assert(__gen::_Cv_unqualified_object<_Value>,
> "Generator value must be a cv-unqualified object type");
> -  using _Reference = __gen::_Reference_t<_Ref, _V>;
> +  using _Reference = __gen::_Reference_t<_Ref, _Val>;
>static_assert(is_reference_v<_Reference>
> || (__gen::_Cv_unqualified_object<_Reference>
> && copy_constructible<_Reference>),
> @@ -737,8 +739,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>bool _M_began = false;
>  };
>
> -  template
> -struct generator<_Ref, _V, _Alloc>::_Iterator
> +  template
> +struct generator<_Ref, _Val, _Alloc>::_Iterator
>  {
>using value_type = _Value;
>using difference_type = ptrdiff_t;
> --
> 2.44.0
>



Re: [PATCH 2/2] libstdc++: fix generator iterator operator* return type

2024-03-26 Thread Jonathan Wakely
On Sat, 23 Mar 2024 at 15:47, Arsen Arsenović  wrote:
>
> Per the standard, the return type of a generators ranges iterator op*
> should be the reference type rather than the yielded type.
>
> The yielded type was used here by mistake.
>
> libstdc++-v3/ChangeLog:
>
> * include/std/generator (generator::_Iterator::operator*): Fix
> return type.
> * testsuite/24_iterators/range_generators/iter_deref_return.cc:
> New test.
> ---
>  libstdc++-v3/include/std/generator|  4 +--
>  .../range_generators/iter_deref_return.cc | 34 +++
>  2 files changed, 36 insertions(+), 2 deletions(-)
>  create mode 100644 
> libstdc++-v3/testsuite/24_iterators/range_generators/iter_deref_return.cc
>
> diff --git a/libstdc++-v3/include/std/generator 
> b/libstdc++-v3/include/std/generator
> index 2d1dcced1e57..789016b5a883 100644
> --- a/libstdc++-v3/include/std/generator
> +++ b/libstdc++-v3/include/std/generator
> @@ -773,12 +773,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>operator++(int)
>{ this->operator++(); }
>
> -  yielded
> +  _Reference
>operator*()
> const noexcept(is_nothrow_move_constructible_v<_Reference>)
>{
> auto& __p = this->_M_coro.promise();
> -   return static_cast(*__p._M_value());
> +   return static_cast<_Reference>(*__p._M_value());
>}
>
>  private:
> diff --git 
> a/libstdc++-v3/testsuite/24_iterators/range_generators/iter_deref_return.cc 
> b/libstdc++-v3/testsuite/24_iterators/range_generators/iter_deref_return.cc
> new file mode 100644
> index ..7bdbf4d489ec
> --- /dev/null
> +++ 
> b/libstdc++-v3/testsuite/24_iterators/range_generators/iter_deref_return.cc
> @@ -0,0 +1,34 @@
> +// { dg-do compile { target c++23 } }
> +// Copyright (C) 2023-2024 Free Software Foundation, Inc.

Just 2024 here.

> +//
> +// This file is part of the GNU ISO C++ Library.  This library is free
> +// software; you can redistribute it and/or modify it under the
> +// terms of the GNU General Public License as published by the
> +// Free Software Foundation; either version 3, or (at your option)
> +// any later version.
> +
> +// This library is distributed in the hope that it will be useful,
> +// but WITHOUT ANY WARRANTY; without even the implied warranty of
> +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +// GNU General Public License for more details.
> +
> +// Under Section 7 of GPL version 3, you are granted additional
> +// permissions described in the GCC Runtime Library Exception, version
> +// 3.1, as published by the Free Software Foundation.
> +
> +// You should have received a copy of the GNU General Public License and
> +// a copy of the GCC Runtime Library Exception along with this program;
> +// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
> +// .


I don't think we want the last two paragraphs about the runtime
exception. That's relevant to code being compiled into the users
binary as inline functions or templates, which doesn't matter for
testcases.

I see we have 10 existing tests that use the runtime exception text,
which I'll fix. For comparison, there are 9000 tests with the GPL
text, so the vast majority don't have the exception.

OK for trunk with the copyright date fixed and the exception text
dropped, thanks.

> +
> +#include 
> +
> +// Check that the return type of iterator::operator* is the reference type.
> +// Pre-op* return type fix, this'd have resulted in a op* return type of 
> const
> +// bool&.
> +
> +std::generator
> +foo();
> +
> +static_assert(std::is_same_v);
> +static_assert(std::is_same_v bool&>);
> --
> 2.44.0
>



[committed] libstdc++: Fix incorrect macro used in #undef in test

2024-03-25 Thread Jonathan Wakely
Tested aarch64-linux. Puhed to trunk.

-- >8 --

This was a copy & paste error.

libstdc++-v3/ChangeLog:

* testsuite/std/text_encoding/requirements.cc: #undef the
correct macro.
---
 libstdc++-v3/testsuite/std/text_encoding/requirements.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/testsuite/std/text_encoding/requirements.cc 
b/libstdc++-v3/testsuite/std/text_encoding/requirements.cc
index a1d5d6baee1..6cd71b68225 100644
--- a/libstdc++-v3/testsuite/std/text_encoding/requirements.cc
+++ b/libstdc++-v3/testsuite/std/text_encoding/requirements.cc
@@ -8,7 +8,7 @@
 # error "Feature-test macro for text_encoding has wrong value in 
"
 #endif
 
-#undef __cpp_lib_expected
+#undef __cpp_lib_text_encoding
 #include 
 #ifndef __cpp_lib_text_encoding
 # error "Feature-test macro for text_encoding missing in "
-- 
2.44.0



[committed] libstdc++: Disable std::formatter specializations (LWG 3944)

2024-03-23 Thread Jonathan Wakely
Tested aarch64-linux. Pushed to trunk.

-- >8 --

This was just approved in Tokyo as a DR for C++23. It doesn't affect us
yet, because we don't implement the __cpp_lib_format_ranges features. We
can add the disabled specializations and add a testcase now though.

libstdc++-v3/ChangeLog:

* include/std/format (formatter): Disable specializations that
would allow sequences of narrow characters to be formatted as
wchar_t without conversion, as per LWG 3944.
* testsuite/std/format/formatter/lwg3944.cc: New test.
---
 libstdc++-v3/include/std/format   | 23 ++
 .../testsuite/std/format/formatter/lwg3944.cc | 31 +++
 2 files changed, 54 insertions(+)
 create mode 100644 libstdc++-v3/testsuite/std/format/formatter/lwg3944.cc

diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index 613016d1a10..22dcb5f24bd 100644
--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -2478,6 +2478,29 @@ namespace __format
 };
   /// @}
 
+#if defined _GLIBCXX_USE_WCHAR_T && __cpp_lib_format_ranges
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // 3944. Formatters converting sequences of char to sequences of wchar_t
+
+  namespace __format { struct __disabled; }
+
+  // std::formatter<__disabled, C> uses the primary template, which is 
disabled.
+  template<>
+struct formatter
+: private formatter<__format::__disabled, wchar_t> { };
+  template<>
+struct formatter
+: private formatter<__format::__disabled, wchar_t> { };
+  template
+struct formatter
+: private formatter<__format::__disabled, wchar_t> { };
+  template
+struct formatter, wchar_t>
+: private formatter<__format::__disabled, wchar_t> { };
+  template
+struct formatter, wchar_t>
+: private formatter<__format::__disabled, wchar_t> { };
+#endif
 
 /// @cond undocumented
 namespace __format
diff --git a/libstdc++-v3/testsuite/std/format/formatter/lwg3944.cc 
b/libstdc++-v3/testsuite/std/format/formatter/lwg3944.cc
new file mode 100644
index 000..ff5f075bcc8
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/format/formatter/lwg3944.cc
@@ -0,0 +1,31 @@
+// { dg-do compile { target c++20 } }
+// { dg-options "-Wno-unused-result" }
+
+// LWG 3944. Formatters converting sequences of char to sequences of wchar_t
+
+#include 
+
+void test_lwg3944()
+{
+  // Ill-formed in C++20 and C++23
+  const char* cstr = "hello";
+  char* str = const_cast(cstr);
+  std::format(L"{}", str); // { dg-error "here" }
+  std::format(L"{}",cstr); // { dg-error "here" }
+
+  // Ill-formed in C++20
+  // In C++23 they give L"['h', 'e', 'l', 'l', 'o']"
+  std::format(L"{}", "hello"); // { dg-error "here" }
+  std::format(L"{}", std::string_view("hello")); // { dg-error "here" }
+  std::format(L"{}", std::string("hello")); // { dg-error "here" }
+#ifdef __cpp_lib_format_ranges
+  // LWG 3944 does not change this, it's still valid.
+  std::format(L"{}", std::vector{'h', 'e', 'l', 'l', 'o'});
+#endif
+}
+
+// { dg-error "std::formatter must be specialized" "" { target *-*-* } 0 }
+// { dg-prune-output "use of deleted function" }
+// { dg-prune-output "no matching function" }
+// { dg-prune-output "has no member named 'parse'" }
+// { dg-prune-output "not a constant expression" }
-- 
2.44.0



[committed] libstdc++: Add __is_in_place_index_v helper and use it in

2024-03-23 Thread Jonathan Wakely
Tested aarch64-linux. Pushed to trunk.

-- >8 --

We already have __is_in_place_type_v for in_place_type_t so adding an
equivalent for in_place_index_t allows us avoid a class template
instantiation for the __not_in_place_tag constraint on the most
commonly-used std::variant::variant(T&&) constructor.

For in_place_type_t we also have a __is_in_place_type class template
defined in terms of the variable template, but that isn't actually used
anywhere. I'm not adding an equivalent for the new variable template,
because that wouldn't be used either.

For GCC 15 we should remove the unused __is_in_place_tag and
__is_in_place_type class templates.

libstdc++-v3/ChangeLog:

* include/bits/utility.h (__is_in_place_index_v): New variable
template.
* include/std/variant (__not_in_place_tag): Define in terms of
variable templates not a class template.
---
 libstdc++-v3/include/bits/utility.h | 6 ++
 libstdc++-v3/include/std/variant| 3 ++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/bits/utility.h 
b/libstdc++-v3/include/bits/utility.h
index 2a741bf7000..9f3b99231b3 100644
--- a/libstdc++-v3/include/bits/utility.h
+++ b/libstdc++-v3/include/bits/utility.h
@@ -223,6 +223,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 using __is_in_place_type = bool_constant<__is_in_place_type_v<_Tp>>;
 
+  template
+inline constexpr bool __is_in_place_index_v = false;
+
+  template
+inline constexpr bool __is_in_place_index_v> = true;
+
 #endif // C++17
 
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__type_pack_element)
diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant
index 4b9002e0917..f79d95db7a8 100644
--- a/libstdc++-v3/include/std/variant
+++ b/libstdc++-v3/include/std/variant
@@ -1414,7 +1414,8 @@ namespace __variant
 
   template
static constexpr bool __not_in_place_tag
- = !__is_in_place_tag<__remove_cvref_t<_Tp>>::value;
+ = !__is_in_place_type_v<__remove_cvref_t<_Tp>>
+ && !__is_in_place_index_v<__remove_cvref_t<_Tp>>;
 
 public:
 #if __cpp_concepts
-- 
2.44.0



[committed] libstdc++: Use std::type_identity_t in as per LWG 3950 [PR114400]

2024-03-23 Thread Jonathan Wakely
Tested aarch64-linux. Pushed to trunk.

-- >8 --

The difference between __type_identity_t and std::type_identity_t is
observable, as demonstrated in the PR. Nobody in LWG seems to think this
an example we should really care about, but it seems easy and harmless
to change this.

libstdc++-v3/ChangeLog:

PR libstdc++/114400
* include/std/string_view (operator==): Use std::type_identity_t
in C++20 instead of our own __type_identity_t.
---
 libstdc++-v3/include/std/string_view | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/std/string_view 
b/libstdc++-v3/include/std/string_view
index e30a9c1768e..a7c5a126461 100644
--- a/libstdc++-v3/include/std/string_view
+++ b/libstdc++-v3/include/std/string_view
@@ -602,15 +602,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // deduction and the other argument gets implicitly converted to the deduced
   // type (see N3766).
 
+#if __cpp_lib_three_way_comparison
   template
 [[nodiscard]]
 constexpr bool
 operator==(basic_string_view<_CharT, _Traits> __x,
-   __type_identity_t> __y)
+  type_identity_t> __y)
 noexcept
 { return __x.size() == __y.size() && __x.compare(__y) == 0; }
 
-#if __cpp_lib_three_way_comparison
   template
 [[nodiscard]]
 constexpr auto
@@ -620,6 +620,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 -> decltype(__detail::__char_traits_cmp_cat<_Traits>(0))
 { return __detail::__char_traits_cmp_cat<_Traits>(__x.compare(__y)); }
 #else
+  template
+[[nodiscard]]
+constexpr bool
+operator==(basic_string_view<_CharT, _Traits> __x,
+  __type_identity_t> __y)
+noexcept
+{ return __x.size() == __y.size() && __x.compare(__y) == 0; }
+
   template
 [[nodiscard]]
 constexpr bool
-- 
2.44.0



[PATCH 2/2] libstdc++: Replace stacktrace effective target with feature test

2024-03-22 Thread Jonathan Wakely
And this replaces an existing custom dg-require- directive with a use of
the new one that checks for a standard feature test macro. I didn't see
any other existing dg-require-xxx directives that can be replaced like
this.

-- >8 --

Remove the dejagnu code for checking whether std::stacktrace is supported
and just use the new dg-require-cpp-feature-test directive to check for
__cpp_lib_stacktrace instead.

libstdc++-v3/ChangeLog:

* testsuite/19_diagnostics/stacktrace/current.cc: Check for
__cpp_lib_stacktrace instead of check for stacktrace ET.
* 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.
* testsuite/19_diagnostics/stacktrace/synopsis.cc: Likewise.
* testsuite/19_diagnostics/stacktrace/version.cc: Likewise.
* testsuite/23_containers/vector/debug/assign4_backtrace_neg.cc:
Likewise.
* testsuite/lib/libstdc++.exp (check_effective_target_stacktrace):
Remove.
---
 .../testsuite/19_diagnostics/stacktrace/current.cc| 2 +-
 libstdc++-v3/testsuite/19_diagnostics/stacktrace/entry.cc | 2 +-
 libstdc++-v3/testsuite/19_diagnostics/stacktrace/hash.cc  | 2 +-
 .../testsuite/19_diagnostics/stacktrace/output.cc | 2 +-
 .../testsuite/19_diagnostics/stacktrace/stacktrace.cc | 2 +-
 .../testsuite/19_diagnostics/stacktrace/synopsis.cc   | 2 +-
 .../testsuite/19_diagnostics/stacktrace/version.cc| 2 +-
 .../23_containers/vector/debug/assign4_backtrace_neg.cc   | 2 +-
 libstdc++-v3/testsuite/lib/libstdc++.exp  | 8 
 9 files changed, 8 insertions(+), 16 deletions(-)

diff --git a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/current.cc 
b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/current.cc
index a27836d27af..b1af5f74fb2 100644
--- a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/current.cc
+++ b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/current.cc
@@ -1,6 +1,6 @@
 // { dg-options "-lstdc++exp" }
 // { dg-do run { target c++23 } }
-// { dg-require-effective-target stacktrace }
+// { dg-require-cpp-feature-test __cpp_lib_stacktrace }
 
 #include 
 #include 
diff --git a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/entry.cc 
b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/entry.cc
index ab016d56400..bb348ebef8f 100644
--- a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/entry.cc
+++ b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/entry.cc
@@ -1,6 +1,6 @@
 // { dg-options "-lstdc++exp" }
 // { dg-do run { target c++23 } }
-// { dg-require-effective-target stacktrace }
+// { dg-require-cpp-feature-test __cpp_lib_stacktrace }
 
 #include 
 #include "testsuite_hooks.h"
diff --git a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/hash.cc 
b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/hash.cc
index 21705098ff0..2176596ae5c 100644
--- a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/hash.cc
+++ b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/hash.cc
@@ -1,6 +1,6 @@
 // { dg-options "-lstdc++exp" }
 // { dg-do run { target c++23 } }
-// { dg-require-effective-target stacktrace }
+// { dg-require-cpp-feature-test __cpp_lib_stacktrace }
 
 #include 
 #include 
diff --git a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/output.cc 
b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/output.cc
index 67f1e0cebaf..e27aea1f508 100644
--- a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/output.cc
+++ b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/output.cc
@@ -1,6 +1,6 @@
 // { dg-options "-lstdc++exp" }
 // { dg-do run { target c++23 } }
-// { dg-require-effective-target stacktrace }
+// { dg-require-cpp-feature-test __cpp_lib_stacktrace }
 // { dg-add-options no_pch }
 
 #include 
diff --git a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc 
b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc
index 5dfa76951df..070c4157471 100644
--- a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc
+++ b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/stacktrace.cc
@@ -1,6 +1,6 @@
 // { dg-options "-lstdc++exp" }
 // { dg-do run { target c++23 } }
-// { dg-require-effective-target stacktrace }
+// { dg-require-cpp-feature-test __cpp_lib_stacktrace }
 
 #include 
 #include "testsuite_allocator.h"
diff --git a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/synopsis.cc 
b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/synopsis.cc
index 9e775b86ac9..b99d382ec26 100644
--- a/libstdc++-v3/testsuite/19_diagnostics/stacktrace/synopsis.cc
+++ b/libstdc++-v3/testsuite/19_diagnostics/stacktrace/synopsis.cc
@@ -1,5 +1,5 @@
 // { dg-do compile { target c++23 } }
-// { dg-require-effective-target stacktrace }
+// { dg-require-cpp-feature-test __cpp_lib_stacktrace }
 // { dg-require-normal-namespace "" }
 // { dg-add-options no_pch }
 
diff 

[PATCH 1/2] libstdc++: Add dg-require-cpp-feature-test to test feature test macros

2024-03-22 Thread Jonathan Wakely
Thoughts? There are only a few uses for this presently, but I can see it
being useful often in future. The library exposes which features it
supports in a standardized way, so we can use those in tests to skip
tests for features that aren't available on all targets.

The obvious downside is that it becomes harder to notice if a particular
feature is missing on all targets, because we don't get FAILs we just
skip all tests as UNSUPPORTED. And the checks for whether 
correctly defines the macro become redundant, because the test won't
even get run if it doesn't. But we won't use this dg-require for many
tests, only the ones where support is target-dependent because it relies
on something non-standard or not available on all targets (like
nl_langinfo_l or libbacktrace).

-- >8 -

This adds a new dejagnu directive which can be used to make a test
depend on a feature test macro such as __cpp_lib_text_encoding. This is
mroe flexible than writing a new dg-require-xxx for each feature.

libstdc++-v3/ChangeLog:

* testsuite/lib/dg-options.exp (dg-require-cpp-feature-test):
New proc.
* testsuite/lib/libstdc++.exp (check_v3_target_cpp_feature_test):
New proc.
* testsuite/std/text_encoding/cons.cc: Use new directive to skip
the test if the __cpp_lib_text_encoding feature test macro is
not defined.
* testsuite/std/text_encoding/requirements.cc: Likewise.
---
 libstdc++-v3/testsuite/lib/dg-options.exp |  9 +
 libstdc++-v3/testsuite/lib/libstdc++.exp  | 15 +++
 libstdc++-v3/testsuite/std/text_encoding/cons.cc  |  1 +
 .../testsuite/std/text_encoding/requirements.cc   |  3 ++-
 4 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/testsuite/lib/dg-options.exp 
b/libstdc++-v3/testsuite/lib/dg-options.exp
index 00ca678a53a..802bfc0b492 100644
--- a/libstdc++-v3/testsuite/lib/dg-options.exp
+++ b/libstdc++-v3/testsuite/lib/dg-options.exp
@@ -277,6 +277,15 @@ proc dg-require-target-fs-lwt { args } {
 return
 }
 
+proc dg-require-cpp-feature-test { n args } {
+if { ![ check_v3_target_cpp_feature_test $args ] } {
+   upvar dg-do-what dg-do-what
+   set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"]
+   return
+}
+return
+}
+
 proc add_options_for_no_pch { flags } {
 # Remove any inclusion of bits/stdc++.h from the options.
 regsub -all -- "-include bits/stdc...h" $flags "" flags
diff --git a/libstdc++-v3/testsuite/lib/libstdc++.exp 
b/libstdc++-v3/testsuite/lib/libstdc++.exp
index 7466fb51c58..2b31c950826 100644
--- a/libstdc++-v3/testsuite/lib/libstdc++.exp
+++ b/libstdc++-v3/testsuite/lib/libstdc++.exp
@@ -1134,6 +1134,21 @@ proc v3_check_preprocessor_condition { name cond { inc 
"" } } {
 return [v3_try_preprocess name $code $flags]
 }
 
+# Return 1 if libstdc++ defines macro for the current target, 0 otherwise.
+proc check_v3_target_cpp_feature_test { cond } {
+global cxxflags
+set cxxflags_saved $cxxflags
+# Use the latest standard, so that all feature test macros are defined.
+# We need to do it here, because this check happens before v3-dg-runtest
+# runs its loop to test multiple times with different -std options.
+# This should be updated when a new -std is added.
+set cxxflags "$cxxflags -std=gnu++26"
+set inc "#include "
+set result [v3_check_preprocessor_condition cpp_feature_test "$cond" $inc]
+set cxxflags $cxxflags_saved
+return $result
+}
+
 # Return 1 if Debug Mode is active, 0 otherwise.
 proc check_v3_target_debug_mode { } {
 global cxxflags
diff --git a/libstdc++-v3/testsuite/std/text_encoding/cons.cc 
b/libstdc++-v3/testsuite/std/text_encoding/cons.cc
index 8fcc2ec8c3b..4196e32ea8b 100644
--- a/libstdc++-v3/testsuite/std/text_encoding/cons.cc
+++ b/libstdc++-v3/testsuite/std/text_encoding/cons.cc
@@ -1,4 +1,5 @@
 // { dg-do run { target c++26 } }
+// { dg-require-cpp-feature-test "__cpp_lib_text_encoding" }
 
 #include 
 #include 
diff --git a/libstdc++-v3/testsuite/std/text_encoding/requirements.cc 
b/libstdc++-v3/testsuite/std/text_encoding/requirements.cc
index a1d5d6baee1..3889b250688 100644
--- a/libstdc++-v3/testsuite/std/text_encoding/requirements.cc
+++ b/libstdc++-v3/testsuite/std/text_encoding/requirements.cc
@@ -1,4 +1,5 @@
 // { dg-do compile { target c++26 } }
+// { dg-require-cpp-feature-test __cpp_lib_text_encoding }
 // { dg-add-options no_pch }
 
 #include 



[committed] libstdc++: Destroy allocators in re-inserted container nodes [PR114401]

2024-03-22 Thread Jonathan Wakely
Tested aarch64-linux. Pushed to trunk.

This should be backported to all branches, as the failure to destroy the
allocators in the re-inserted nodes results in potential resource leaks.

-- >8 --

The allocator objects in container node handles were not being destroyed
after the node was re-inserted into a container. They are stored in a
union and so need to be explicitly destroyed when the node becomes
empty. The containers were zeroing the node handle's pointer, which
makes it empty, causing the handle's destructor to think there's nothign
to clean up.

Add a new member function to the node handle which destroys the
allocator and zeros the pointer. Change the containers to call that
instead of just changing the pointer manually.

We can also remove the _M_empty member of the union which is not
necessary.

libstdc++-v3/ChangeLog:

PR libstdc++/114401
* include/bits/hashtable.h (_Hashtable::_M_reinsert_node): Call
release() on node handle instead of just zeroing its pointer.
(_Hashtable::_M_reinsert_node_multi): Likewise.
(_Hashtable::_M_merge_unique): Likewise.
(_Hashtable::_M_merge_multi): Likewise.
* include/bits/node_handle.h (_Node_handle_common::release()):
New member function.
(_Node_handle_common::_Optional_alloc::_M_empty): Remove
unnecessary union member.
(_Node_handle_common): Declare _Hashtable as a friend.
* include/bits/stl_tree.h (_Rb_tree::_M_reinsert_node_unique):
Call release() on node handle instead of just zeroing its
pointer.
(_Rb_tree::_M_reinsert_node_equal): Likewise.
(_Rb_tree::_M_reinsert_node_hint_unique): Likewise.
(_Rb_tree::_M_reinsert_node_hint_equal): Likewise.
* testsuite/23_containers/multiset/modifiers/114401.cc: New test.
* testsuite/23_containers/set/modifiers/114401.cc: New test.
* testsuite/23_containers/unordered_multiset/modifiers/114401.cc: New 
test.
* testsuite/23_containers/unordered_set/modifiers/114401.cc: New test.
---
 libstdc++-v3/include/bits/hashtable.h |  12 +-
 libstdc++-v3/include/bits/node_handle.h   |  19 ++-
 libstdc++-v3/include/bits/stl_tree.h  |  12 +-
 .../multiset/modifiers/114401.cc  | 125 +
 .../23_containers/set/modifiers/114401.cc | 125 +
 .../unordered_multiset/modifiers/114401.cc| 126 ++
 .../unordered_set/modifiers/114401.cc | 126 ++
 7 files changed, 530 insertions(+), 15 deletions(-)
 create mode 100644 
libstdc++-v3/testsuite/23_containers/multiset/modifiers/114401.cc
 create mode 100644 libstdc++-v3/testsuite/23_containers/set/modifiers/114401.cc
 create mode 100644 
libstdc++-v3/testsuite/23_containers/unordered_multiset/modifiers/114401.cc
 create mode 100644 
libstdc++-v3/testsuite/23_containers/unordered_set/modifiers/114401.cc

diff --git a/libstdc++-v3/include/bits/hashtable.h 
b/libstdc++-v3/include/bits/hashtable.h
index c3ef7a0a3d5..cd3e1ac297c 100644
--- a/libstdc++-v3/include/bits/hashtable.h
+++ b/libstdc++-v3/include/bits/hashtable.h
@@ -1036,7 +1036,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // DR 1189.
   // reserve, if present, comes from _Rehash_base.
 
-#if __cplusplus > 201402L
+#if __glibcxx_node_extract // >= C++17
   /// Re-insert an extracted node into a container with unique keys.
   insert_return_type
   _M_reinsert_node(node_type&& __nh)
@@ -1078,7 +1078,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  {
__ret.position
  = _M_insert_unique_node(__bkt, __code, __nh._M_ptr);
-   __nh._M_ptr = nullptr;
+   __nh.release();
__ret.inserted = true;
  }
  }
@@ -1098,7 +1098,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
auto __code = this->_M_hash_code(__k);
auto __ret
  = _M_insert_multi_node(__hint._M_cur, __code, __nh._M_ptr);
-   __nh._M_ptr = nullptr;
+   __nh.release();
return __ret;
   }
 
@@ -1200,7 +1200,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
  auto __nh = __src.extract(__pos);
  _M_insert_unique_node(__bkt, __code, __nh._M_ptr, __n_elt);
- __nh._M_ptr = nullptr;
+ __nh.release();
  __n_elt = 1;
}
  else if (__n_elt != 1)
@@ -1227,10 +1227,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
= _M_src_hash_code(__src.hash_function(), __k, *__pos._M_cur);
  auto __nh = __src.extract(__pos);
  __hint = _M_insert_multi_node(__hint, __code, __nh._M_ptr)._M_cur;
- __nh._M_ptr = nullptr;
+ __nh.release();
}
}
-#endif // C++17
+#endif // C++17 __glibcxx_node_extract
 
 private:
   // Helper rehash method used when keys are unique.
diff --git a/libstdc++-v3/include/bits/node_handle.h 

Re: [PATCH] libstdc++: Constrain std::vector default constructor [PR113841]

2024-03-22 Thread Jonathan Wakely
Pushed to trunk. Backport to gcc-13 needed too, as the changes to use
concepts for std::pair constructors are on that branch.

On Tue, 19 Mar 2024 at 15:59, Jonathan Wakely  wrote:
>
> This fixes the problem in the PR, which is revealed by the new
> concept-based constraints on std::pair constructors in C++20 mode. That
> makes this a C++20 regression, as the PR's example compiles with C++17.
>
> We need something similar for std::basic_string too, which I'll do
> later.
>
> Any comments?
>
> Tested aarch64-linux.
>
> -- >8 --
>
> This is needed to avoid errors outside the immediate context when
> evaluating is_default_constructible_v> when A is not
> default constructible.
>
> To avoid diagnostic regressions for 23_containers/vector/48101_neg.cc we
> need to make the std::allocator partial specializations default
> constructible, which they probably should have been anyway.
>
> libstdc++-v3/ChangeLog:
>
> PR libstdc++/113841
> * include/bits/allocator.h (allocator): Add default
> constructor to partial specializations for cv-qualified types.
> * include/bits/stl_vector.h (_Vector_impl::_Vector_impl()):
> Constrain so that it's only present if the allocator is default
> constructible.
> * include/bits/stl_bvector.h (_Bvector_impl::_Bvector_impl()):
> Likewise.
> * testsuite/23_containers/vector/cons/113841.cc: New test.
> ---
>  libstdc++-v3/include/bits/allocator.h |  3 ++
>  libstdc++-v3/include/bits/stl_bvector.h   |  3 ++
>  libstdc++-v3/include/bits/stl_vector.h|  3 ++
>  .../23_containers/vector/cons/113841.cc   | 34 +++
>  4 files changed, 43 insertions(+)
>  create mode 100644 libstdc++-v3/testsuite/23_containers/vector/cons/113841.cc
>
> diff --git a/libstdc++-v3/include/bits/allocator.h 
> b/libstdc++-v3/include/bits/allocator.h
> index ff4f5b9137b..9e75b37fce7 100644
> --- a/libstdc++-v3/include/bits/allocator.h
> +++ b/libstdc++-v3/include/bits/allocator.h
> @@ -254,6 +254,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>  {
>  public:
>typedef _Tp value_type;
> +  allocator() { }
>template allocator(const allocator<_Up>&) { }
>  };
>
> @@ -262,6 +263,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>  {
>  public:
>typedef _Tp value_type;
> +  allocator() { }
>template allocator(const allocator<_Up>&) { }
>  };
>
> @@ -270,6 +272,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>  {
>  public:
>typedef _Tp value_type;
> +  allocator() { }
>template allocator(const allocator<_Up>&) { }
>  };
>/// @endcond
> diff --git a/libstdc++-v3/include/bits/stl_bvector.h 
> b/libstdc++-v3/include/bits/stl_bvector.h
> index a3343d95b36..d567e26f4e4 100644
> --- a/libstdc++-v3/include/bits/stl_bvector.h
> +++ b/libstdc++-v3/include/bits/stl_bvector.h
> @@ -593,6 +593,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
> _GLIBCXX20_CONSTEXPR
> _Bvector_impl() _GLIBCXX_NOEXCEPT_IF(
>   is_nothrow_default_constructible<_Bit_alloc_type>::value)
> +#if __cpp_concepts
> +   requires is_default_constructible_v<_Bit_alloc_type>
> +#endif
> : _Bit_alloc_type()
> { }
>
> diff --git a/libstdc++-v3/include/bits/stl_vector.h 
> b/libstdc++-v3/include/bits/stl_vector.h
> index a8d387f40a1..31169711a48 100644
> --- a/libstdc++-v3/include/bits/stl_vector.h
> +++ b/libstdc++-v3/include/bits/stl_vector.h
> @@ -135,6 +135,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
> _GLIBCXX20_CONSTEXPR
> _Vector_impl() _GLIBCXX_NOEXCEPT_IF(
> is_nothrow_default_constructible<_Tp_alloc_type>::value)
> +#if __cpp_lib_concepts
> +   requires is_default_constructible_v<_Tp_alloc_type>
> +#endif
> : _Tp_alloc_type()
> { }
>
> diff --git a/libstdc++-v3/testsuite/23_containers/vector/cons/113841.cc 
> b/libstdc++-v3/testsuite/23_containers/vector/cons/113841.cc
> new file mode 100644
> index 000..a7721d27f79
> --- /dev/null
> +++ b/libstdc++-v3/testsuite/23_containers/vector/cons/113841.cc
> @@ -0,0 +1,34 @@
> +// { dg-do compile { target c++20 } }
> +
> +#include 
> +
> +template
> +struct Alloc
> +{
> +  using value_type = T;
> +
> +  Alloc(int) { } // not default constructible
> +
> +  template Alloc(const Alloc&) { }
> +
> +  T* allocate(std::size_t n) { return std::allocator().allocate(n); }
> +  void deallocate(T* p, std::size_t n) { std::allocator().deallocate(p, 
> n); }
> +};
> +
> +template struct wrap { T t; };
> +
> +template void do_adl(T&) { }
> +
> +void test_pr113841()
> +{
> +  using test_type = std::vector>;
> +  std::pair>* h = nullptr;
> +  do_adl(h);
> +}
> +
> +void test_pr113841_bool()
> +{
> +  using test_type = std::vector>;
> +  std::pair>* h = nullptr;
> +  do_adl(h);
> +}
> --
> 2.44.0
>



[committed] libstdc++: Reorder feature test macro definitions

2024-03-22 Thread Jonathan Wakely
Tested aarch64-linux. Pushed to trunk.

-- >8 --

Put the C++23 generator and tuple_like ones before the C++26 ones.

libstdc++-v3/ChangeLog:

* include/bits/version.def (generator, tuple_like): Move earlier
in the file.
* include/bits/version.h: Regenerate.
---
 libstdc++-v3/include/bits/version.def | 34 +++
 libstdc++-v3/include/bits/version.h   | 40 +--
 2 files changed, 37 insertions(+), 37 deletions(-)

diff --git a/libstdc++-v3/include/bits/version.def 
b/libstdc++-v3/include/bits/version.def
index 26e62c6a9b2..5ad44941bff 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -1637,6 +1637,15 @@ ftms = {
   };
 };
 
+ftms = {
+  name = generator;
+  values = {
+v = 202207;
+cxxmin = 23;
+extra_cond = "__glibcxx_coroutine";
+  };
+};
+
 ftms = {
   name = ios_noreplace;
   values = {
@@ -1718,6 +1727,14 @@ ftms = {
   };
 };
 
+ftms = {
+  name = tuple_like;
+  values = {
+v = 202207;
+cxxmin = 23;
+  };
+};
+
 ftms = {
   name = unreachable;
   values = {
@@ -1771,23 +1788,6 @@ ftms = {
   };
 };
 
-ftms = {
-  name = generator;
-  values = {
-v = 202207;
-cxxmin = 23;
-extra_cond = "__glibcxx_coroutine";
-  };
-};
-
-ftms = {
-  name = tuple_like;
-  values = {
-v = 202207;
-cxxmin = 23;
-  };
-};
-
 // Standard test specifications.
 stds[97] = ">= 199711L";
 stds[03] = ">= 199711L";
diff --git a/libstdc++-v3/include/bits/version.h 
b/libstdc++-v3/include/bits/version.h
index 23c8c09ab4b..460a3e0116a 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -1823,6 +1823,16 @@
 #endif /* !defined(__cpp_lib_forward_like) && 
defined(__glibcxx_want_forward_like) */
 #undef __glibcxx_want_forward_like
 
+#if !defined(__cpp_lib_generator)
+# if (__cplusplus >= 202100L) && (__glibcxx_coroutine)
+#  define __glibcxx_generator 202207L
+#  if defined(__glibcxx_want_all) || defined(__glibcxx_want_generator)
+#   define __cpp_lib_generator 202207L
+#  endif
+# endif
+#endif /* !defined(__cpp_lib_generator) && defined(__glibcxx_want_generator) */
+#undef __glibcxx_want_generator
+
 #if !defined(__cpp_lib_ios_noreplace)
 # if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED
 #  define __glibcxx_ios_noreplace 202207L
@@ -1913,6 +1923,16 @@
 #endif /* !defined(__cpp_lib_to_underlying) && 
defined(__glibcxx_want_to_underlying) */
 #undef __glibcxx_want_to_underlying
 
+#if !defined(__cpp_lib_tuple_like)
+# if (__cplusplus >= 202100L)
+#  define __glibcxx_tuple_like 202207L
+#  if defined(__glibcxx_want_all) || defined(__glibcxx_want_tuple_like)
+#   define __cpp_lib_tuple_like 202207L
+#  endif
+# endif
+#endif /* !defined(__cpp_lib_tuple_like) && defined(__glibcxx_want_tuple_like) 
*/
+#undef __glibcxx_want_tuple_like
+
 #if !defined(__cpp_lib_unreachable)
 # if (__cplusplus >= 202100L)
 #  define __glibcxx_unreachable 202202L
@@ -1973,24 +1993,4 @@
 #endif /* !defined(__cpp_lib_to_string) && defined(__glibcxx_want_to_string) */
 #undef __glibcxx_want_to_string
 
-#if !defined(__cpp_lib_generator)
-# if (__cplusplus >= 202100L) && (__glibcxx_coroutine)
-#  define __glibcxx_generator 202207L
-#  if defined(__glibcxx_want_all) || defined(__glibcxx_want_generator)
-#   define __cpp_lib_generator 202207L
-#  endif
-# endif
-#endif /* !defined(__cpp_lib_generator) && defined(__glibcxx_want_generator) */
-#undef __glibcxx_want_generator
-
-#if !defined(__cpp_lib_tuple_like)
-# if (__cplusplus >= 202100L)
-#  define __glibcxx_tuple_like 202207L
-#  if defined(__glibcxx_want_all) || defined(__glibcxx_want_tuple_like)
-#   define __cpp_lib_tuple_like 202207L
-#  endif
-# endif
-#endif /* !defined(__cpp_lib_tuple_like) && defined(__glibcxx_want_tuple_like) 
*/
-#undef __glibcxx_want_tuple_like
-
 #undef __glibcxx_want_all
-- 
2.44.0



[committed] libstdc++: Use feature test macros in

2024-03-22 Thread Jonathan Wakely
Tested aarch64-linux. Pushed to trunk.

-- >8 --

The preprocessor checks for __cplusplus in  should
use the appropriate feature test macros instead of __cplusplus, namely
__glibcxx_raw_memory_algorithms and __cpp_constexpr_dynamic_alloc.

For the latter, we want to check the compiler macro not the library's
__cpp_lib_constexpr_dynamic_alloc, because the latter is not defined for
freestanding but std::construct_at needs to be.

libstdc++-v3/ChangeLog:

* include/bits/stl_construct.h (destroy_at, construct_at): Guard
with feature test macros instead of just __cplusplus.
---
 libstdc++-v3/include/bits/stl_construct.h | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/libstdc++-v3/include/bits/stl_construct.h 
b/libstdc++-v3/include/bits/stl_construct.h
index 7c394072b50..dc08fb7ea33 100644
--- a/libstdc++-v3/include/bits/stl_construct.h
+++ b/libstdc++-v3/include/bits/stl_construct.h
@@ -74,7 +74,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-#if __cplusplus >= 201703L
+#if __glibcxx_raw_memory_algorithms // >= C++17
   template 
 _GLIBCXX20_CONSTEXPR inline void
 destroy_at(_Tp* __location)
@@ -88,7 +88,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__location->~_Tp();
 }
 
-#if __cplusplus >= 202002L
+#if __cpp_constexpr_dynamic_alloc // >= C++20
   template
 constexpr auto
 construct_at(_Tp* __location, _Args&&... __args)
@@ -108,7 +108,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 inline void
 _Construct(_Tp* __p, _Args&&... __args)
 {
-#if __cplusplus >= 202002L
+#if __cpp_constexpr_dynamic_alloc // >= C++20
   if (std::__is_constant_evaluated())
{
  // Allow std::_Construct to be used in constant expressions.
@@ -145,7 +145,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 _GLIBCXX14_CONSTEXPR inline void
 _Destroy(_Tp* __pointer)
 {
-#if __cplusplus > 201703L
+#if __cpp_constexpr_dynamic_alloc // >= C++20
   std::destroy_at(__pointer);
 #else
   __pointer->~_Tp();
@@ -188,7 +188,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   static_assert(is_destructible<_Value_type>::value,
"value type is destructible");
 #endif
-#if __cplusplus >= 202002L
+#if __cpp_constexpr_dynamic_alloc // >= C++20
   if (std::__is_constant_evaluated())
return std::_Destroy_aux::__destroy(__first, __last);
 #endif
@@ -237,7 +237,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   static_assert(is_destructible<_Value_type>::value,
"value type is destructible");
 #endif
-#if __cplusplus >= 202002L
+#if __cpp_constexpr_dynamic_alloc // >= C++20
   if (std::__is_constant_evaluated())
return std::_Destroy_n_aux::__destroy_n(__first, __count);
 #endif
@@ -245,7 +245,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__destroy_n(__first, __count);
 }
 
-#if __cplusplus >= 201703L
+#if __glibcxx_raw_memory_algorithms // >= C++17
   template 
 _GLIBCXX20_CONSTEXPR inline void
 destroy(_ForwardIterator __first, _ForwardIterator __last)
-- 
2.44.0



[committed] libstdc++: Replace std::result_of with __invoke_result_t [PR114394]

2024-03-22 Thread Jonathan Wakely
Tested aarch64-linux. Pushed to trunk.

-- >8 --

Replace std::result_of with std::invoke_result, as specified in the
standard since C++17, to avoid deprecated warnings for std::result_of.

We don't have __invoke_result_t in C++11 mode, so add it as an alias
template for __invoke_result<>::type (which is what std::result_of uses
as its base class, so there's no change in functionality).

This fixes warnings given by Clang 18.

libstdc++-v3/ChangeLog:

PR libstdc++/114394
* include/std/functional (bind): Use __invoke_result_t instead
of result_of::type.
* include/std/type_traits (__invoke_result_t): New alias
template.
* testsuite/20_util/bind/ref_neg.cc: Adjust prune pattern.
---
 libstdc++-v3/include/std/functional| 2 +-
 libstdc++-v3/include/std/type_traits   | 4 
 libstdc++-v3/testsuite/20_util/bind/ref_neg.cc | 2 +-
 3 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/std/functional 
b/libstdc++-v3/include/std/functional
index e02be00abe5..766558b3ce0 100644
--- a/libstdc++-v3/include/std/functional
+++ b/libstdc++-v3/include/std/functional
@@ -556,7 +556,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template
using _Res_type_impl
- = typename result_of< _Fn&(_Mu_type<_BArgs, _CallArgs>&&...) >::type;
+ = __invoke_result_t<_Fn&, _Mu_type<_BArgs, _CallArgs>&&...>;
 
   template
using _Res_type = _Res_type_impl<_Functor, _CallArgs, _Bound_args...>;
diff --git a/libstdc++-v3/include/std/type_traits 
b/libstdc++-v3/include/std/type_traits
index 21402fd8c13..b441bf9908f 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -2664,6 +2664,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Functor, _ArgTypes...
   >::type
 { };
+
+  // __invoke_result_t (std::invoke_result_t for C++11)
+  template
+using __invoke_result_t = typename __invoke_result<_Fn, _Args...>::type;
   /// @endcond
 
   template
diff --git a/libstdc++-v3/testsuite/20_util/bind/ref_neg.cc 
b/libstdc++-v3/testsuite/20_util/bind/ref_neg.cc
index 4a1ed8dda5f..2db9fa8276a 100644
--- a/libstdc++-v3/testsuite/20_util/bind/ref_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/bind/ref_neg.cc
@@ -50,7 +50,7 @@ void test02()
 
 // Ignore the reasons for deduction/substitution failure in the headers.
 // Arrange for the match to work on installed trees as well as build trees.
-// { dg-prune-output "no type named 'type' in 'struct std::result_of" }
+// { dg-prune-output "no type named 'type' in 'struct std::__invoke_result" }
 
 int main()
 {
-- 
2.44.0



Re: _LIBCXX_DEBUG value initialized singular iterators assert failures in std algorithms [PR104316]

2024-03-21 Thread Jonathan Wakely
On Wed, 20 Mar 2024 at 18:11, François Dumont wrote:
>
> As proposed below I also updated gcc-13 branch.

Great, thanks.

>
>  libstdc++: [_GLIBCXX_DEBUG] Define __cpp_lib_null_iterators
>
>  _GLIBCXX_DEBUG has now fully N3344 compliant iterator checks, we
> can define
>  __cpp_lib_null_iterators macros like the normal mode.
>
>  libstdc++-v3/ChangeLog:
>
>  * include/std/iterator (__cpp_lib_null_iterators): Define
> regardless of
>  _GLIBCXX_DEBUG.
>  * include/std/version (__cpp_lib_null_iterators): Likewise.
>
> François
>
>
> On 20/03/2024 10:02, Jonathan Wakely wrote:
> > On Wed, 20 Mar 2024 at 05:59, François Dumont wrote:
> >> Thanks to you doc:
> >>
> >>   libstdc++: [_GLIBCXX_DEBUG] Define __[glibcxx,cpp_lib]_null_iterators
> >>
> >>   _GLIBCXX_DEBUG has now fully N3344 compliant iterator checks, we
> >> can define
> >>   __glibcxx_null_iterators and __cpp_lib_null_iterators macros like
> >> the normal
> >>   mode.
> >>
> >>   libstdc++-v3/ChangeLog:
> >>
> >>   * version.def (null_iterators): Remove extra_cond.
> >>   * version.h: Regenerate.
> >>
> >> Ok to commit ?
> > Please don't bother talking about __glibcxx_null_iterators in the
> > commit message, that's an implementation detail that always mirrors
> > the standard-defined __cpp_lib_null_iterators one. The first line of
> > the commit will be much easier to read without that.
> >
> > OK with that change, thanks.
> >
> >> I already noticed that GCC 13 has no version.h file so no backport 
> >> question.
> > It has no version.h but it still has the macros:
> >
> > include/std/iterator:# define __cpp_lib_null_iterators 201304L
> > include/std/version:# define __cpp_lib_null_iterators 201304L
> >
> > Those definitions can be made to not depend on _GLIBCXX_DEBUG.
> >


Re: _LIBCXX_DEBUG value initialized singular iterators assert failures in std algorithms [PR104316]

2024-03-20 Thread Jonathan Wakely
On Wed, 20 Mar 2024 at 05:59, François Dumont wrote:
>
> Thanks to you doc:
>
>  libstdc++: [_GLIBCXX_DEBUG] Define __[glibcxx,cpp_lib]_null_iterators
>
>  _GLIBCXX_DEBUG has now fully N3344 compliant iterator checks, we
> can define
>  __glibcxx_null_iterators and __cpp_lib_null_iterators macros like
> the normal
>  mode.
>
>  libstdc++-v3/ChangeLog:
>
>  * version.def (null_iterators): Remove extra_cond.
>  * version.h: Regenerate.
>
> Ok to commit ?

Please don't bother talking about __glibcxx_null_iterators in the
commit message, that's an implementation detail that always mirrors
the standard-defined __cpp_lib_null_iterators one. The first line of
the commit will be much easier to read without that.

OK with that change, thanks.

> I already noticed that GCC 13 has no version.h file so no backport question.

It has no version.h but it still has the macros:

include/std/iterator:# define __cpp_lib_null_iterators 201304L
include/std/version:# define __cpp_lib_null_iterators 201304L

Those definitions can be made to not depend on _GLIBCXX_DEBUG.



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

2024-03-19 Thread Jonathan Wakely
Tested x86_64-linux. Pushed to trunk.

Not a regression, but worth backporting.

-- >8 --

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.
---
 libstdc++-v3/include/bits/random.tcc |  2 +-
 .../random/binomial_distribution/114359.cc   | 12 
 2 files changed, 13 insertions(+), 1 deletion(-)
 create mode 100644 
libstdc++-v3/testsuite/26_numerics/random/binomial_distribution/114359.cc

diff --git a/libstdc++-v3/include/bits/random.tcc 
b/libstdc++-v3/include/bits/random.tcc
index ade416390b3..8216883c448 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 000..c1e4c380bf9
--- /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
+}
-- 
2.44.0



[PATCH] libstdc++: Constrain std::vector default constructor [PR113841]

2024-03-19 Thread Jonathan Wakely
This fixes the problem in the PR, which is revealed by the new
concept-based constraints on std::pair constructors in C++20 mode. That
makes this a C++20 regression, as the PR's example compiles with C++17.

We need something similar for std::basic_string too, which I'll do
later.

Any comments?

Tested aarch64-linux.

-- >8 --

This is needed to avoid errors outside the immediate context when
evaluating is_default_constructible_v> when A is not
default constructible.

To avoid diagnostic regressions for 23_containers/vector/48101_neg.cc we
need to make the std::allocator partial specializations default
constructible, which they probably should have been anyway.

libstdc++-v3/ChangeLog:

PR libstdc++/113841
* include/bits/allocator.h (allocator): Add default
constructor to partial specializations for cv-qualified types.
* include/bits/stl_vector.h (_Vector_impl::_Vector_impl()):
Constrain so that it's only present if the allocator is default
constructible.
* include/bits/stl_bvector.h (_Bvector_impl::_Bvector_impl()):
Likewise.
* testsuite/23_containers/vector/cons/113841.cc: New test.
---
 libstdc++-v3/include/bits/allocator.h |  3 ++
 libstdc++-v3/include/bits/stl_bvector.h   |  3 ++
 libstdc++-v3/include/bits/stl_vector.h|  3 ++
 .../23_containers/vector/cons/113841.cc   | 34 +++
 4 files changed, 43 insertions(+)
 create mode 100644 libstdc++-v3/testsuite/23_containers/vector/cons/113841.cc

diff --git a/libstdc++-v3/include/bits/allocator.h 
b/libstdc++-v3/include/bits/allocator.h
index ff4f5b9137b..9e75b37fce7 100644
--- a/libstdc++-v3/include/bits/allocator.h
+++ b/libstdc++-v3/include/bits/allocator.h
@@ -254,6 +254,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 {
 public:
   typedef _Tp value_type;
+  allocator() { }
   template allocator(const allocator<_Up>&) { }
 };
 
@@ -262,6 +263,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 {
 public:
   typedef _Tp value_type;
+  allocator() { }
   template allocator(const allocator<_Up>&) { }
 };
 
@@ -270,6 +272,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 {
 public:
   typedef _Tp value_type;
+  allocator() { }
   template allocator(const allocator<_Up>&) { }
 };
   /// @endcond
diff --git a/libstdc++-v3/include/bits/stl_bvector.h 
b/libstdc++-v3/include/bits/stl_bvector.h
index a3343d95b36..d567e26f4e4 100644
--- a/libstdc++-v3/include/bits/stl_bvector.h
+++ b/libstdc++-v3/include/bits/stl_bvector.h
@@ -593,6 +593,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_GLIBCXX20_CONSTEXPR
_Bvector_impl() _GLIBCXX_NOEXCEPT_IF(
  is_nothrow_default_constructible<_Bit_alloc_type>::value)
+#if __cpp_concepts
+   requires is_default_constructible_v<_Bit_alloc_type>
+#endif
: _Bit_alloc_type()
{ }
 
diff --git a/libstdc++-v3/include/bits/stl_vector.h 
b/libstdc++-v3/include/bits/stl_vector.h
index a8d387f40a1..31169711a48 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -135,6 +135,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_GLIBCXX20_CONSTEXPR
_Vector_impl() _GLIBCXX_NOEXCEPT_IF(
is_nothrow_default_constructible<_Tp_alloc_type>::value)
+#if __cpp_lib_concepts
+   requires is_default_constructible_v<_Tp_alloc_type>
+#endif
: _Tp_alloc_type()
{ }
 
diff --git a/libstdc++-v3/testsuite/23_containers/vector/cons/113841.cc 
b/libstdc++-v3/testsuite/23_containers/vector/cons/113841.cc
new file mode 100644
index 000..a7721d27f79
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/cons/113841.cc
@@ -0,0 +1,34 @@
+// { dg-do compile { target c++20 } }
+
+#include 
+
+template
+struct Alloc
+{
+  using value_type = T;
+
+  Alloc(int) { } // not default constructible
+
+  template Alloc(const Alloc&) { }
+
+  T* allocate(std::size_t n) { return std::allocator().allocate(n); }
+  void deallocate(T* p, std::size_t n) { std::allocator().deallocate(p, n); 
}
+};
+
+template struct wrap { T t; };
+
+template void do_adl(T&) { }
+
+void test_pr113841()
+{
+  using test_type = std::vector>;
+  std::pair>* h = nullptr;
+  do_adl(h);
+}
+
+void test_pr113841_bool()
+{
+  using test_type = std::vector>;
+  std::pair>* h = nullptr;
+  do_adl(h);
+}
-- 
2.44.0



[PATCH] libstdc++: Use feature test macros in

2024-03-19 Thread Jonathan Wakely
Does anybody see any issues with making this change?

The __cpp_constexpr_dynamic_alloc macro is defined with -std=c++2a
since Clang 10.0.0 so this won't result in std::construct_at
disappearing by anybody using libstdc++ with Clang.

Tested x86_64-linux and aarch64-linux. Basic smoke tests checked with
Clang 16 too.

-- >8 --

The preprocessor checks for __cplusplus in  should
use the appropriate feature test macros instead of __cplusplus, namely
__glibcxx_raw_memory_algorithms and __cpp_constexpr_dynamic_alloc.

For the latter, we want to check the compiler macro not the library's
__cpp_lib_constexpr_dynamic_alloc, because the latter is not defined for
freestanding but std::construct_at needs to be.

libstdc++-v3/ChangeLog:

* include/bits/stl_construct.h (destroy_at, construct_at): Guard
with feature test macros instead of just __cplusplus.
---
 libstdc++-v3/include/bits/stl_construct.h | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/libstdc++-v3/include/bits/stl_construct.h 
b/libstdc++-v3/include/bits/stl_construct.h
index 7c394072b50..dc08fb7ea33 100644
--- a/libstdc++-v3/include/bits/stl_construct.h
+++ b/libstdc++-v3/include/bits/stl_construct.h
@@ -74,7 +74,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-#if __cplusplus >= 201703L
+#if __glibcxx_raw_memory_algorithms // >= C++17
   template 
 _GLIBCXX20_CONSTEXPR inline void
 destroy_at(_Tp* __location)
@@ -88,7 +88,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__location->~_Tp();
 }
 
-#if __cplusplus >= 202002L
+#if __cpp_constexpr_dynamic_alloc // >= C++20
   template
 constexpr auto
 construct_at(_Tp* __location, _Args&&... __args)
@@ -108,7 +108,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 inline void
 _Construct(_Tp* __p, _Args&&... __args)
 {
-#if __cplusplus >= 202002L
+#if __cpp_constexpr_dynamic_alloc // >= C++20
   if (std::__is_constant_evaluated())
{
  // Allow std::_Construct to be used in constant expressions.
@@ -145,7 +145,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 _GLIBCXX14_CONSTEXPR inline void
 _Destroy(_Tp* __pointer)
 {
-#if __cplusplus > 201703L
+#if __cpp_constexpr_dynamic_alloc // >= C++20
   std::destroy_at(__pointer);
 #else
   __pointer->~_Tp();
@@ -188,7 +188,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   static_assert(is_destructible<_Value_type>::value,
"value type is destructible");
 #endif
-#if __cplusplus >= 202002L
+#if __cpp_constexpr_dynamic_alloc // >= C++20
   if (std::__is_constant_evaluated())
return std::_Destroy_aux::__destroy(__first, __last);
 #endif
@@ -237,7 +237,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   static_assert(is_destructible<_Value_type>::value,
"value type is destructible");
 #endif
-#if __cplusplus >= 202002L
+#if __cpp_constexpr_dynamic_alloc // >= C++20
   if (std::__is_constant_evaluated())
return std::_Destroy_n_aux::__destroy_n(__first, __count);
 #endif
@@ -245,7 +245,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__destroy_n(__first, __count);
 }
 
-#if __cplusplus >= 201703L
+#if __glibcxx_raw_memory_algorithms // >= C++17
   template 
 _GLIBCXX20_CONSTEXPR inline void
 destroy(_ForwardIterator __first, _ForwardIterator __last)
-- 
2.44.0



Re: _LIBCXX_DEBUG value initialized singular iterators assert failures in std algorithms [PR104316]

2024-03-19 Thread Jonathan Wakely
On Tue, 19 Mar 2024 at 09:31, Jonathan Wakely wrote:
>
> On Mon, 18 Mar 2024 at 21:38, François Dumont wrote:
> >
> > Both committed now.
> >
> > Just to confirm, those 2 last patches should be backported to gcc-13
> > branch, right ?
>
> Yes please.
>
> >
> > I might have a try to update version.h but if you want to do it before
> > don't hesitate.
>
> You'll need to have 'autogen' installed to do it (I'm going to update
> the docs to describe that today).

I've documented it in a new "Generated files" section at the end of
https://gcc.gnu.org/onlinedocs/libstdc++/manual/appendix_porting.html#build_hacking.generated



[committed] libstdc++: Regenerate in maintainer mode

2024-03-19 Thread Jonathan Wakely
Tested x86_64-linux. Pushed to trunk.

I've taken the liberty of assuming that the change to
gcc/doc/install.texi is sufficiently "obviously true" to not require
separate approval.

-- >8 --

This is a generated header but regenerating it requires the manual step
of running 'make -C include update-version' in the libstdc++ build dir.
Make it regenerate automatically when --enable-maintainer-mode is used.

libstdc++-v3/ChangeLog:

* include/Makefile.am [MAINTAINER_MODE]: Add target to
automatically update .
* include/Makefile.in: Regenerate.

gcc/ChangeLog:

* doc/install.texi (Prerequisites): Document use of autogen for
libstdc++.
---
 gcc/doc/install.texi | 2 ++
 libstdc++-v3/include/Makefile.am | 6 ++
 libstdc++-v3/include/Makefile.in | 4 
 3 files changed, 12 insertions(+)

diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index e3650e0c4f4..014ca25aa62 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -545,6 +545,8 @@ Necessary to run @samp{make check} for @file{fixinc}.
 Necessary to regenerate the top level @file{Makefile.in} file from
 @file{Makefile.tpl} and @file{Makefile.def}.
 
+Necessary to regenerate the @file{bits/version.h} header for libstdc++.
+
 @item Flex version 2.5.4 (or later)
 
 Necessary when modifying @file{*.l} files.
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 64152351ed0..cb902de36ae 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -1480,6 +1480,12 @@ update-version:
cd ${bits_srcdir} && \
autogen version.def
 
+if MAINTAINER_MODE
+# Regenerate it automatically in maintainer mode.
+${bits_srcdir}/version.h: ${bits_srcdir}/version.def ${bits_srcdir}/version.tpl
+   $(MAKE) update-version
+endif
+
 # The real deal.
 install-data-local: install-headers
 install-headers:



[committed] libstdc++: Update docs on build process and generated files

2024-03-19 Thread Jonathan Wakely
Pushed to trunk.

-- >8 --

There are several more sub-directories below 'src' now, with lots more
conveience libraries. Document them all as of GCC 14.

Also document how to regenerate the generated headers under include/bits
and how to update the tzdata.zi file.

libstdc++-v3/ChangeLog:

* doc/xml/manual/build_hacking.xml: Document generated files.
Update list of convenience libraries and sub-directories under
the src directory.
* doc/html/*: Regenerate.
---
 libstdc++-v3/doc/html/index.html  |   2 +-
 libstdc++-v3/doc/html/manual/appendix.html|   2 +-
 .../doc/html/manual/appendix_porting.html | 119 +++--
 libstdc++-v3/doc/html/manual/index.html   |   2 +-
 libstdc++-v3/doc/xml/manual/build_hacking.xml | 164 --
 5 files changed, 262 insertions(+), 27 deletions(-)

diff --git a/libstdc++-v3/doc/xml/manual/build_hacking.xml 
b/libstdc++-v3/doc/xml/manual/build_hacking.xml
index 36f659cea4b..077c0632a79 100644
--- a/libstdc++-v3/doc/xml/manual/build_hacking.xml
+++ b/libstdc++-v3/doc/xml/manual/build_hacking.xml
@@ -554,9 +554,9 @@ baseline file.
  make src


- Generates two convenience libraries, one for C++98 and one for
- C++11, various compatibility files for shared and static
- libraries, and then collects all the generated bits and creates
+ Generates several convenience libraries,
+ various compatibility files for shared and static libraries,
+ and then collects all the generated bits and creates
  the final libstdc++ libraries.
   
 
@@ -566,8 +566,8 @@ baseline file.


  Generates a libtool convenience library,
- libc++98convenience with language-support
- routines. Uses the -std=gnu++98 dialect.
+ libc++98convenience with the library components
+ defined by C++98. Uses the -std=gnu++98 dialect.

  
  
@@ -576,8 +576,84 @@ baseline file.


  Generates a libtool convenience library,
- libc++11convenience with language-support
- routines. Uses the -std=gnu++11 dialect.
+ libc++11convenience with the library components
+ that were added or changed in C++11.
+ Uses the -std=gnu++11 dialect.
+   
+ 
+ 
+   
+ make src/c++17
+   
+   
+ Generates a libtool convenience library,
+ libc++17convenience with the library components
+ that were added or changed in C++17.
+ Uses the -std=gnu++17 dialect.
+   
+ 
+ 
+   
+ make src/c++20
+   
+   
+ Generates a libtool convenience library,
+ libc++20convenience with the library components
+ that were added or changed in C++20.
+ Uses the -std=gnu++20 dialect.
+   
+ 
+ 
+   
+ make src/c++23
+   
+   
+ Generates a libtool convenience library,
+ libc++23convenience with the library components
+ that were added or changed in C++23.
+ At the time of writing (GCC 14) this convenience library is included
+ in libstdc++exp.a and not in the final
+ libstdc++ libraries.
+ Uses the -std=gnu++23 dialect.
+   
+ 
+ 
+   
+ make src/filesystem
+   
+   
+ Generates a libtool convenience library,
+ libstdc++fsconvenience,
+ and a standalone static library,
+ libstdc++fs.a.
+ These contain definitions of the Filesystem TS extensions.
+ Uses the -std=gnu++17 dialect.
+   
+ 
+ 
+   
+ make src/libbacktrace
+   
+   
+ Generates a libtool convenience library,
+ libstdc++_libbacktrace,
+ containing the libbacktrace definitions used by the C++23
+ std::stacktrace feature.
+   
+ 
+ 
+   
+ make src/experimental
+   
+   
+ Generates a standalone static library,
+ libstdc++exp.a, containing the symbol definitions
+ for experimental features and extensions. This collects the convenience
+ libraries libstdc++fsconvenience,
+ libstdc++_libbacktrace, and
+ (at the time of writing) libc++23convenience
+ and combines them into one.
+ Uses the -std=gnu++17 dialect.

  
  
@@ -591,10 +667,11 @@ baseline file.

 

- Then, collects all the generated convenience libraries, adds in
- any required compatibility objects, and creates the final shared
- and static libraries: libstdc++.so and
- libstdc++.a.
+ Then, collects all the generated convenience libraries that weren't
+ added to libstdc++exp.a,
+ adds in any required compatibility objects,
+ and creates the final shared and static libraries:
+ libstdc++.so and libstdc++.a.

 
  
@@ -604,4 +681,69 @@ baseline file.
 
  
 
+Generated 
files
+
+
+  Some files in the libstdc++ source tree are auto-generated from other files.
+  In general, these are not regenerated automatically, so it must be done
+  manually when the files they depend on are updated.
+
+
+
+ 
+   
+   The header file
+   include/bits/version.h
+   is generated from version.def and
+   version.tpl in the same directory.
+   After editing those files, either run autogen version.def
+   in 

[committed] libstdc++: Fix Python scripts to output the correct filename

2024-03-19 Thread Jonathan Wakely
Tested x86_64-linux. Pushed to trunk.

-- >8 --

These scripts both print "generated by $file, do not edit" header but
one of them prints the wrong filename. Use the built-in __file__
attribute to ensure it's correct.

contrib/ChangeLog:

* unicode/gen_libstdcxx_unicode_data.py: Fix header of generated
file to name the correct script.

libstdc++-v3/ChangeLog:

* include/bits/text_encoding-data.h: Regenerate.
* include/bits/unicode-data.h: Regenerate.
* scripts/gen_text_encoding_data.py: Fix header of generated
file to name the correct script.
---
 contrib/unicode/gen_libstdcxx_unicode_data.py  | 6 --
 libstdc++-v3/include/bits/text_encoding-data.h | 3 ++-
 libstdc++-v3/include/bits/unicode-data.h   | 2 +-
 libstdc++-v3/scripts/gen_text_encoding_data.py | 5 -
 4 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/contrib/unicode/gen_libstdcxx_unicode_data.py 
b/contrib/unicode/gen_libstdcxx_unicode_data.py
index 2341a442f6a..da2f6ee66bf 100755
--- a/contrib/unicode/gen_libstdcxx_unicode_data.py
+++ b/contrib/unicode/gen_libstdcxx_unicode_data.py
@@ -29,9 +29,11 @@
 import sys
 import re
 import math
+import os
 
-print("""// Generated by contrib/unicode/gen_std_format_width.py, do not edit.
-
+self = os.path.basename(__file__)
+print("// Generated by contrib/unicode/{}, do not edit.".format(self))
+print("""
 // Copyright The GNU Toolchain Authors.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
diff --git a/libstdc++-v3/include/bits/text_encoding-data.h 
b/libstdc++-v3/include/bits/text_encoding-data.h
index 81bd94e6c3a..d6c34f895f5 100644
--- a/libstdc++-v3/include/bits/text_encoding-data.h
+++ b/libstdc++-v3/include/bits/text_encoding-data.h
@@ -1,4 +1,5 @@
-// Generated by gen_text_encoding_data.py, do not edit.
+// Generated by scripts/gen_text_encoding_data.py, do not edit.
+
 
 // Copyright The GNU Toolchain Authors.
 //
diff --git a/libstdc++-v3/include/bits/unicode-data.h 
b/libstdc++-v3/include/bits/unicode-data.h
index 69b8f2926c3..e39a6c45f6c 100644
--- a/libstdc++-v3/include/bits/unicode-data.h
+++ b/libstdc++-v3/include/bits/unicode-data.h
@@ -1,4 +1,4 @@
-// Generated by contrib/unicode/gen_std_format_width.py, do not edit.
+// Generated by contrib/unicode/gen_libstdcxx_unicode_data.py, do not edit.
 
 // Copyright The GNU Toolchain Authors.
 //
diff --git a/libstdc++-v3/scripts/gen_text_encoding_data.py 
b/libstdc++-v3/scripts/gen_text_encoding_data.py
index 13792b5f5e7..e11b26e69fc 100755
--- a/libstdc++-v3/scripts/gen_text_encoding_data.py
+++ b/libstdc++-v3/scripts/gen_text_encoding_data.py
@@ -26,12 +26,15 @@
 
 import sys
 import csv
+import os
 
 if len(sys.argv) != 2:
 print("Usage: %s " % sys.argv[0], file=sys.stderr)
 sys.exit(1)
 
-print("""// Generated by gen_text_encoding_data.py, do not edit.
+self = os.path.basename(__file__)
+print("// Generated by scripts/{}, do not edit.".format(self))
+print("""
 
 // Copyright The GNU Toolchain Authors.
 //
-- 
2.44.0



[committed] libstdc++: Fix typos in MemoryChecker assertion messages in PSTL tests

2024-03-19 Thread Jonathan Wakely
Tested x86_64-linux. Pushed to trunk.

-- >8 --

This has been reported upstream.

libstdc++-v3/ChangeLog:

* testsuite/util/pstl/test_utils.h: Fix typos in comments.
---
 libstdc++-v3/testsuite/util/pstl/test_utils.h | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/libstdc++-v3/testsuite/util/pstl/test_utils.h 
b/libstdc++-v3/testsuite/util/pstl/test_utils.h
index e35084eabb2..55b510098a0 100644
--- a/libstdc++-v3/testsuite/util/pstl/test_utils.h
+++ b/libstdc++-v3/testsuite/util/pstl/test_utils.h
@@ -252,7 +252,7 @@ struct MemoryChecker {
 MemoryChecker(MemoryChecker&& other) : _value(other.value()) {
 // check for EXPECT_TRUE(state() != alive_state, ...) has not been 
done since
 // compiler can optimize out the move ctor call that results in false 
positive failure
-EXPECT_TRUE(other.state() == alive_state, "wrong effect from 
MemoryChecker(MemoryChecker&&): attemp to construct an object from non-existing 
object");
+EXPECT_TRUE(other.state() == alive_state, "wrong effect from 
MemoryChecker(MemoryChecker&&): attempt to construct an object from 
non-existing object");
 // set constructed state and increment counter for living object
 inc_alive_objects();
 _state = alive_state;
@@ -260,15 +260,15 @@ struct MemoryChecker {
 MemoryChecker(const MemoryChecker& other) : _value(other.value()) {
 // check for EXPECT_TRUE(state() != alive_state, ...) has not been 
done since
 // compiler can optimize out the copy ctor call that results in false 
positive failure
-EXPECT_TRUE(other.state() == alive_state, "wrong effect from 
MemoryChecker(const MemoryChecker&): attemp to construct an object from 
non-existing object");
+EXPECT_TRUE(other.state() == alive_state, "wrong effect from 
MemoryChecker(const MemoryChecker&): attempt to construct an object from 
non-existing object");
 // set constructed state and increment counter for living object
 inc_alive_objects();
 _state = alive_state;
 }
 MemoryChecker& operator=(MemoryChecker&& other) {
 // check if we do not assign over uninitialized memory
-EXPECT_TRUE(state() == alive_state, "wrong effect from 
MemoryChecker::operator=(MemoryChecker&& other): attemp to assign to 
non-existing object");
-EXPECT_TRUE(other.state() == alive_state, "wrong effect from 
MemoryChecker::operator=(MemoryChecker&& other): attemp to assign from 
non-existing object");
+EXPECT_TRUE(state() == alive_state, "wrong effect from 
MemoryChecker::operator=(MemoryChecker&& other): attempt to assign to 
non-existing object");
+EXPECT_TRUE(other.state() == alive_state, "wrong effect from 
MemoryChecker::operator=(MemoryChecker&& other): attempt to assign from 
non-existing object");
 // just assign new value, counter is the same, state is the same
 _value = other.value();
 
@@ -276,8 +276,8 @@ struct MemoryChecker {
 }
 MemoryChecker& operator=(const MemoryChecker& other) {
 // check if we do not assign over uninitialized memory
-EXPECT_TRUE(state() == alive_state, "wrong effect from 
MemoryChecker::operator=(const MemoryChecker& other): attemp to assign to 
non-existing object");
-EXPECT_TRUE(other.state() == alive_state, "wrong effect from 
MemoryChecker::operator=(const MemoryChecker& other): attemp to assign from 
non-existing object");
+EXPECT_TRUE(state() == alive_state, "wrong effect from 
MemoryChecker::operator=(const MemoryChecker& other): attempt to assign to 
non-existing object");
+EXPECT_TRUE(other.state() == alive_state, "wrong effect from 
MemoryChecker::operator=(const MemoryChecker& other): attempt to assign from 
non-existing object");
 // just assign new value, counter is the same, state is the same
 _value = other.value();
 
@@ -285,7 +285,7 @@ struct MemoryChecker {
 }
 ~MemoryChecker() {
 // check if we do not double destruct the object
-EXPECT_TRUE(state() == alive_state, "wrong effect from 
~MemoryChecker(): attemp to destroy non-existing object");
+EXPECT_TRUE(state() == alive_state, "wrong effect from 
~MemoryChecker(): attempt to destroy non-existing object");
 // set destructed state and decrement counter for living object
 static_cast(_state) = dead_state;
 dec_alive_objects();
-- 
2.44.0



[committed] libstdc++: Begin lifetime of storage in std::vector [PR114367]

2024-03-19 Thread Jonathan Wakely
Tested x86_64-linux. Pushed to trunk. Backport to gcc-13 to follow.

-- >8 --

This doesn't cause a problem with GCC, but Clang correctly diagnoses a
bug in the code. The objects in the allocated storage need to begin
their lifetime before we start using them.

This change uses the allocator's construct function instead of using
std::construct_at directly, in order to support fancy pointers.

libstdc++-v3/ChangeLog:

PR libstdc++/114367
* include/bits/stl_bvector.h (_M_allocate): Use allocator's
construct function to begin lifetime of words.
---
 libstdc++-v3/include/bits/stl_bvector.h | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/libstdc++-v3/include/bits/stl_bvector.h 
b/libstdc++-v3/include/bits/stl_bvector.h
index 2c8b892b07a..a3343d95b36 100644
--- a/libstdc++-v3/include/bits/stl_bvector.h
+++ b/libstdc++-v3/include/bits/stl_bvector.h
@@ -674,13 +674,13 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
   _M_allocate(size_t __n)
   {
_Bit_pointer __p = _Bit_alloc_traits::allocate(_M_impl, _S_nword(__n));
-#if __cpp_lib_is_constant_evaluated
+#if __cpp_lib_is_constant_evaluated && __cpp_constexpr_dynamic_alloc
if (std::is_constant_evaluated())
-   {
- __n = _S_nword(__n);
- for (size_t __i = 0; __i < __n; ++__i)
-   __p[__i] = 0ul;
-   }
+ {
+   __n = _S_nword(__n);
+   for (size_t __i = 0; __i < __n; ++__i)
+ std::construct_at(std::to_address(__p) + __i);
+ }
 #endif
return __p;
   }
-- 
2.44.0



Re: [PATCH] libstdc++, Darwin: Do not use dev/null as the file for executables.

2024-03-19 Thread Jonathan Wakely
On Tue, 19 Mar 2024 at 10:55, Iain Sandoe wrote:
>
> Note that Windows-based platforms do something quite similar, but always
> use the same (x.exe) filename.  I wonder, in passing, if that makes a
> vulnerability in parallel testing (I chose to avoid the possibility for
> Darwin).

Parallel testing should use a separate directory for each runtest
process, so each x.exe is in a separate directory. That's a
predictable name that could be used by an attacker, but I don't think
it's a problem specific to parallel testing. A single runtest process
has the same behaviour.

> Tested on x86_64-darwin21, x86_64-linux-gnu,
> OK for trunk?
> back-ports where applicable (I did not yet check)?
> thanks
> Iain
>
> --- 8< ---
>
> Darwin has a separate debug linker, which is invoked when the command
> line contains source files and debug is enabled.
>
> Using /dev/null as the executable name does not, therefore, work when
> debug is enabled, since the debug linker does not accept /dev/null as
> a valid executable name.
>
> The leads to incorrectly UNSUPPORTED testcases because of the unintended
> error result from the test compilation.
>
> The solution here is to use a temporary file that is deleted at the
> end of the test (which is the mechanism used elsewhere)
>
> libstdc++-v3/ChangeLog:
>
> * testsuite/lib/libstdc++.exp (v3_target_compile): Instead of
> /dev/null, use a temporary file for test executables on Darwin.
>
> Signed-off-by: Iain Sandoe 
> ---
>  libstdc++-v3/testsuite/lib/libstdc++.exp | 20 +++-
>  1 file changed, 19 insertions(+), 1 deletion(-)
>
> diff --git a/libstdc++-v3/testsuite/lib/libstdc++.exp 
> b/libstdc++-v3/testsuite/lib/libstdc++.exp
> index 58804ecab26..4ae4cecb169 100644
> --- a/libstdc++-v3/testsuite/lib/libstdc++.exp
> +++ b/libstdc++-v3/testsuite/lib/libstdc++.exp
> @@ -615,11 +615,15 @@ proc v3_target_compile { source dest type options } {
> }
>  }
>
> +# For Windows and Darwin we might want to create a temporary file.
> +# note that it needs deleteting.

Capital N for Note, and "deleting".

OK for trunk and branches with that change.


> +set file_to_delete ""
>  # Small adjustment for Windows hosts.
>  if { $dest == "/dev/null"
>   && [info exists ::env(OS)] && [string match "Windows*" $::env(OS)] 
> } {
> if { $type == "executable" } {
> set dest "x.exe"
> +   set file_to_delete ${dest}
> } else {
> # Windows uses special file named "nul" as a substitute for
> # /dev/null
> @@ -627,6 +631,15 @@ proc v3_target_compile { source dest type options } {
> }
>  }
>
> +# Using /dev/null as the executable name does not work on Darwin when
> +# debug is enabled, since the debug linker does not accept /dev/null as
> +# a valid executable name.
> +if { $dest == "/dev/null" && [istarget *-*-darwin*]
> + && $type == "executable" } {
> +   set dest dev-null-[pid].exe
> +   set file_to_delete ${dest}
> +}
> +
>  lappend options "compiler=$cxx_final"
>  lappend options "timeout=[timeout_value]"
>
> @@ -637,7 +650,12 @@ proc v3_target_compile { source dest type options } {
>  }
>
>  set comp_output [target_compile $source $dest $type $options]
> -
> +if { $type == "executable" && $file_to_delete != "" } {
> +   file delete $file_to_delete
> +   if { [istarget *-*-darwin*] && [file exists $file_to_delete.dSYM] } {
> +   file delete -force $file_to_delete.dSYM
> +   }
> +}
>  return $comp_output
>  }
>
> --
> 2.39.2 (Apple Git-143)
>



Re: _LIBCXX_DEBUG value initialized singular iterators assert failures in std algorithms [PR104316]

2024-03-19 Thread Jonathan Wakely
On Mon, 18 Mar 2024 at 21:38, François Dumont wrote:
>
> Both committed now.
>
> Just to confirm, those 2 last patches should be backported to gcc-13
> branch, right ?

Yes please.

>
> I might have a try to update version.h but if you want to do it before
> don't hesitate.

You'll need to have 'autogen' installed to do it (I'm going to update
the docs to describe that today).



Re: [PATCH] cpp: new built-in __EXP_COUNTER__

2024-03-18 Thread Jonathan Wakely
On Mon, 18 Mar 2024 at 16:46, Kaz Kylheku  wrote:
>
> On 2024-03-18 00:30, Jonathan Wakely wrote:
> >>+@item __EXP_COUNTER__
> >>+This macro's name means "(macro) expansion counter".
> >>+Outside of macro replacement sequences, it expands to the integer
> >>+token @code{1}.  This make it possible to easily test for the presence
> >>+of this feature using conditional directives such as
> >>+@code{#if __EXP_COUNTER__}.
> >
> > It's a macro, so you can just use '#ifdef __EXP_COUNTER__' to test if
> > it's supported. Is this additional behaviour necessary?
>
> Thanks for looking at the patch.
>
> The macro has to be defined, but it doesn't have to be 1.
>
> Outside a macro body, it could just appear defined
> with an empty value, as if by #define __EXP_COUNTER__.
>
> When I dump the predefined macros of a nearby GCC installation, I
> see very few empty ones:
>
>$ echo | gcc -dM -E - | awk 'NF == 2'
>#define __USER_LABEL_PREFIX__
>#define __REGISTER_PREFIX__
>
> The __EXP_COUNTER__ and __UEXP_COUNTER__ symbols are
> intended for suffix and infix use, so they are roughly in
> a kind of category with those those two.

I don't feel strongly about the value, it seems fine to define it as 1
too. I just thought it was a bit strange to explicitly mention testing
its value to detect support, when #ifdef seems simpler and more
"correct" (as in, it just checks if it's defined, and thevalue is
irrelevant).

>
> I will make that change, and also fix the grammar error
> and remove the conflict-promoting ChangeLog changes.
>



Re: _LIBCXX_DEBUG value initialized singular iterators assert failures in std algorithms [PR104316]

2024-03-18 Thread Jonathan Wakely
On Sun, 17 Mar 2024 at 16:52, François Dumont  wrote:
>
>
> >
> > OK for trunk, thanks!
> >
> > I think this is OK to backport to 13 too.
> >
> > Maybe after this we can define the __cpp_lib_null_itetators macro for
> > debug mode?
> >
> After this fix of local_iterator I think we can indeed.
>
> In fact the added 11316.cc was already passing for
> unordered_set<>::local_iterator but simply because we were missing the
> singular check. Both issues solved with this patch.
>
> I found the version.def file to cleanup but no idea how to regenerate
> version.h from it so I'll let you do it, ok ?

Sure, I can do that. To regenerate it run 'make update-version' in the
libstdc++-v3/include build directory.

>
>  libstdc++: Fix _Safe_local_iterator<>::_M_valid_range
>
>  Unordered container local_iterator range shall not contain any singular
>  iterator unless both iterators are value-initialized.
>
>  libstdc++-v3/ChangeLog:
>
>  * include/debug/safe_local_iterator.tcc
>  (_Safe_local_iterator::_M_valid_range): Add
> _M_value_initialized and
>  _M_singular checks.
>  * testsuite/23_containers/unordered_set/debug/114316.cc:
> New test case.
>
>
> Ok to commit ?

OK.



Re: _LIBCXX_DEBUG value initialized singular iterators assert failures in std algorithms [PR104316]

2024-03-18 Thread Jonathan Wakely
On Sun, 17 Mar 2024 at 18:14, François Dumont  wrote:
>
> I was a little bit too confident below. After review of all _M_singular
> usages I found another necessary fix.
>
> After this one for sure we will be able to define
> __cpp_lib_null_iterators even in Debug mode.
>
>  libstdc++: Fix N3344 behavior on _Safe_iterator::_M_can_advance
>
>  We shall be able to advance from a 0 offset a value-initialized
> iterator.
>
>  libstdc++-v3/ChangeLog:
>
>  * include/debug/safe_iterator.tcc
> (_Safe_iterator<>::_M_can_advance):
>  Accept 0 offset advance on value-initialized iterator.
>  * testsuite/23_containers/vector/debug/n3644.cc: New test case.
>
> Ok to commit ?


OK, thanks.


> François
>
>
> On 17/03/2024 17:52, François Dumont wrote:
> >
> >>
> >> OK for trunk, thanks!
> >>
> >> I think this is OK to backport to 13 too.
> >>
> >> Maybe after this we can define the __cpp_lib_null_itetators macro for
> >> debug mode?
> >>
> > After this fix of local_iterator I think we can indeed.
> >
> > In fact the added 11316.cc was already passing for
> > unordered_set<>::local_iterator but simply because we were missing the
> > singular check. Both issues solved with this patch.
> >
> > I found the version.def file to cleanup but no idea how to regenerate
> > version.h from it so I'll let you do it, ok ?
> >
> > libstdc++: Fix _Safe_local_iterator<>::_M_valid_range
> >
> > Unordered container local_iterator range shall not contain any
> > singular
> > iterator unless both iterators are value-initialized.
> >
> > libstdc++-v3/ChangeLog:
> >
> > * include/debug/safe_local_iterator.tcc
> > (_Safe_local_iterator::_M_valid_range): Add
> > _M_value_initialized and
> > _M_singular checks.
> > * testsuite/23_containers/unordered_set/debug/114316.cc:
> > New test case.
> >
> >
> > Ok to commit ?
> >
> > François



Re: [PATCH] cpp: new built-in __EXP_COUNTER__

2024-03-18 Thread Jonathan Wakely

On 18/03/24 07:30 +, Jonathan Wakely wrote:

On 21/04/22 04:31 -0700, Kaz Kylheku wrote:

libcpp/ChangeLog
2022-04-21  Kaz Kylheku  

This change introduces a pair of related macros
__EXP_COUNTER__ and __UEXP_COUNTER__.  These macros access
integer values which enumerate macro expansions.
They can be used for the purposes of obtaining, unique
identifiers (within the scope of a translation unit), as a
replacement for unreliable hacks based on __LINE__.

Outside of macro expansions, these macros expand to 1,
so they are easy to test for in portable code that needs
to fall back on something, like __LINE__.

* gcc/doc/cpp.texi (__EXP_COUNTER__, __UEXP_COUNTER__):
Special built-in macros documented.

* libcpp/include/cpplib.h (struct cpp_macro): New members of
type long long: exp_number and uexp_number.  These members are
used to attach the current exp_counter value, and the parent
context's copy of it to a new macro expansion.  The special
macros then just access these.
(enum cpp_builtin_type): New enumeration members,
BT_EXP_COUNTER and BT_UEXP_COUNTER.

* libcpp/macro.cc (exp_counter): New static variable for
counting expansions.  There is an existing one,
num_expanded_macros_counter, but that has its own purpose and
is incremented in a specific place.  Plus it uses a narrower
integer type.
(_cpp_builtin_number_text): Change the local variable "number"
from linenum_type to unsigned long long, so it holds at least
64 bit values.  Handle the BT_EXP_COUNTER and BT_UEXP_COUNTER
cases.  These just have to see if there is a current macro, and
retrieve the values from it, otherwise do nothing so that the
default 1 is produced.  In the case of BT_UEXP_COUNTER, if the
value is zero, we don't use it, so 1 emerges.  The sprintf of
the number is adjusted to use the right conversion specifier
for the wider type.  Space is already being reserved for
a 64 bit decimal.
(enter_macro_context): After processing the macro arguments,
if any, we increment exp_counter and attach its new value to
the macro's context structure in the exp_number member.  We
also calculate the macro's uexp_number: the parent context's
exp_number.  This is tricky: we have to chase the previous
macro context.  This works if the macro is object-like, or has
no parameters.  If it has parameters, there is a parameter
context, and so we have to climb one more flight of stairs to
get to the real context.

gcc/testsuite/ChangeLog
2022-04-21  Kaz Kylheku  

* gcc.dg/cpp/expcounter1.c: New test.
* gcc.dg/cpp/expcounter2.c: New test.
* gcc.dg/cpp/expcounter3.c: New test.
* gcc.dg/cpp/expcounter4.c: New test.
* gcc.dg/cpp/expcounter5.c: New test.

Signed-off-by: Kaz Kylheku 
---
gcc/doc/cpp.texi   | 81 ++
gcc/testsuite/ChangeLog|  8 +++
gcc/testsuite/gcc.dg/cpp/expcounter1.c | 16 +
gcc/testsuite/gcc.dg/cpp/expcounter2.c | 21 +++
gcc/testsuite/gcc.dg/cpp/expcounter3.c | 22 +++
gcc/testsuite/gcc.dg/cpp/expcounter4.c | 22 +++
gcc/testsuite/gcc.dg/cpp/expcounter5.c | 28 +
libcpp/ChangeLog   | 49 
libcpp/include/cpplib.h|  8 +++
libcpp/init.cc |  2 +
libcpp/macro.cc| 44 +-
11 files changed, 299 insertions(+), 2 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/cpp/expcounter1.c
create mode 100644 gcc/testsuite/gcc.dg/cpp/expcounter2.c
create mode 100644 gcc/testsuite/gcc.dg/cpp/expcounter3.c
create mode 100644 gcc/testsuite/gcc.dg/cpp/expcounter4.c
create mode 100644 gcc/testsuite/gcc.dg/cpp/expcounter5.c

diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi
index 90b2767e39a..d52450958d7 100644
--- a/gcc/doc/cpp.texi
+++ b/gcc/doc/cpp.texi
@@ -1941,6 +1941,87 @@ generate unique identifiers.  Care must be 
taken to ensure that

@code{__COUNTER__} is not expanded prior to inclusion of precompiled headers
which use it.  Otherwise, the precompiled headers will not be used.

+@item __EXP_COUNTER__
+This macro's name means "(macro) expansion counter".
+Outside of macro replacement sequences, it expands to the integer
+token @code{1}.  This make it possible to easily test for the presence
+of this feature using conditional directives such as
+@code{#if __EXP_COUNTER__}.


It's a macro, so you can just use '#ifdef __EXP_COUNTER__' to test if
it's supported. Is this additional behaviour necessary?


+When @code{__EXP_COUNTER__} occurs in the replacement token sequence
+of a macro, it expands to positive decimal integer token which


expands to _a_ positive decimal integer token?



Re: [PATCH] cpp: new built-in __EXP_COUNTER__

2024-03-18 Thread Jonathan Wakely

On 21/04/22 04:31 -0700, Kaz Kylheku wrote:

libcpp/ChangeLog
2022-04-21  Kaz Kylheku  

This change introduces a pair of related macros
__EXP_COUNTER__ and __UEXP_COUNTER__.  These macros access
integer values which enumerate macro expansions.
They can be used for the purposes of obtaining, unique
identifiers (within the scope of a translation unit), as a
replacement for unreliable hacks based on __LINE__.

Outside of macro expansions, these macros expand to 1,
so they are easy to test for in portable code that needs
to fall back on something, like __LINE__.

* gcc/doc/cpp.texi (__EXP_COUNTER__, __UEXP_COUNTER__):
Special built-in macros documented.

* libcpp/include/cpplib.h (struct cpp_macro): New members of
type long long: exp_number and uexp_number.  These members are
used to attach the current exp_counter value, and the parent
context's copy of it to a new macro expansion.  The special
macros then just access these.
(enum cpp_builtin_type): New enumeration members,
BT_EXP_COUNTER and BT_UEXP_COUNTER.

* libcpp/macro.cc (exp_counter): New static variable for
counting expansions.  There is an existing one,
num_expanded_macros_counter, but that has its own purpose and
is incremented in a specific place.  Plus it uses a narrower
integer type.
(_cpp_builtin_number_text): Change the local variable "number"
from linenum_type to unsigned long long, so it holds at least
64 bit values.  Handle the BT_EXP_COUNTER and BT_UEXP_COUNTER
cases.  These just have to see if there is a current macro, and
retrieve the values from it, otherwise do nothing so that the
default 1 is produced.  In the case of BT_UEXP_COUNTER, if the
value is zero, we don't use it, so 1 emerges.  The sprintf of
the number is adjusted to use the right conversion specifier
for the wider type.  Space is already being reserved for
a 64 bit decimal.
(enter_macro_context): After processing the macro arguments,
if any, we increment exp_counter and attach its new value to
the macro's context structure in the exp_number member.  We
also calculate the macro's uexp_number: the parent context's
exp_number.  This is tricky: we have to chase the previous
macro context.  This works if the macro is object-like, or has
no parameters.  If it has parameters, there is a parameter
context, and so we have to climb one more flight of stairs to
get to the real context.

gcc/testsuite/ChangeLog
2022-04-21  Kaz Kylheku  

* gcc.dg/cpp/expcounter1.c: New test.
* gcc.dg/cpp/expcounter2.c: New test.
* gcc.dg/cpp/expcounter3.c: New test.
* gcc.dg/cpp/expcounter4.c: New test.
* gcc.dg/cpp/expcounter5.c: New test.

Signed-off-by: Kaz Kylheku 
---
gcc/doc/cpp.texi   | 81 ++
gcc/testsuite/ChangeLog|  8 +++
gcc/testsuite/gcc.dg/cpp/expcounter1.c | 16 +
gcc/testsuite/gcc.dg/cpp/expcounter2.c | 21 +++
gcc/testsuite/gcc.dg/cpp/expcounter3.c | 22 +++
gcc/testsuite/gcc.dg/cpp/expcounter4.c | 22 +++
gcc/testsuite/gcc.dg/cpp/expcounter5.c | 28 +
libcpp/ChangeLog   | 49 
libcpp/include/cpplib.h|  8 +++
libcpp/init.cc |  2 +
libcpp/macro.cc| 44 +-
11 files changed, 299 insertions(+), 2 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/cpp/expcounter1.c
create mode 100644 gcc/testsuite/gcc.dg/cpp/expcounter2.c
create mode 100644 gcc/testsuite/gcc.dg/cpp/expcounter3.c
create mode 100644 gcc/testsuite/gcc.dg/cpp/expcounter4.c
create mode 100644 gcc/testsuite/gcc.dg/cpp/expcounter5.c

diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi
index 90b2767e39a..d52450958d7 100644
--- a/gcc/doc/cpp.texi
+++ b/gcc/doc/cpp.texi
@@ -1941,6 +1941,87 @@ generate unique identifiers.  Care must be 
taken to ensure that

@code{__COUNTER__} is not expanded prior to inclusion of precompiled headers
which use it.  Otherwise, the precompiled headers will not be used.

+@item __EXP_COUNTER__
+This macro's name means "(macro) expansion counter".
+Outside of macro replacement sequences, it expands to the integer
+token @code{1}.  This make it possible to easily test for the presence
+of this feature using conditional directives such as
+@code{#if __EXP_COUNTER__}.


It's a macro, so you can just use '#ifdef __EXP_COUNTER__' to test if
it's supported. Is this additional behaviour necessary?


+When @code{__EXP_COUNTER__} occurs in the replacement token sequence
+of a macro, it expands to positive decimal integer token which


expands to _a_ positive decimal integer token?


+uniquely identifies the expansion, within a translation unit.
+Unlike 

Re: _LIBCXX_DEBUG value initialized singular iterators assert failures in std algorithms [PR104316]

2024-03-17 Thread Jonathan Wakely
On Sat, 16 Mar 2024, 12:16 François Dumont,  wrote:

> With the patch, sorry.
>
> On 14/03/2024 22:49, François Dumont wrote:
> > Hi
> >
> > This is what I started to do.
> >
> > For now I haven't touch to __cpp_lib_null_iterators definition as
> > _Safe_local_iterator still need some work.
> >
> > libstdc++: Implement N3644 on _Safe_iterator<> [PR114316]
> >
> > Consider range of value-initialized iterators as valid and empty.
> >
> > libstdc++-v3/ChangeLog:
> >
> > PR libstdc++/114316
> > * include/debug/safe_iterator.tcc
> > (_Safe_iterator<>::_M_valid_range):
> > First check if both iterators are value-initialized before
> > checking if
> > singular.
> > * testsuite/23_containers/set/debug/114316.cc: New test case.
> > * testsuite/23_containers/vector/debug/114316.cc: New test case.
> >
> > Tested under Linux x86_64, ok to commit ?
>

OK for trunk, thanks!

I think this is OK to backport to 13 too.

Maybe after this we can define the __cpp_lib_null_itetators macro for debug
mode?


>
> > François
> >
> >
> > On 12/03/2024 10:52, Jonathan Wakely wrote:
> >> On Tue, 12 Mar 2024 at 01:03, Jonathan Wakely 
> >> wrote:
> >>> On Tue, 12 Mar 2024 at 00:55, Maciej Miera 
> >>> wrote:
> >>>>
> >>>>
> >>>> Wiadomość napisana przez Jonathan Wakely  w
> >>>> dniu 11.03.2024, o godz. 21:40:
> >>>>
> >>>> On Mon, 11 Mar 2024 at 20:07, Maciej Miera 
> >>>> wrote:
> >>>>
> >>>>
> >>>> Hello,
> >>>>
> >>>> I have tried to introduce an extra level of safety to my codebase
> >>>> and utilize _GLIBCXX_DEBUG in my test builds in order to catch
> >>>> faulty iterators.
> >>>> However, I have encountered the following problem: I would like to
> >>>> utilize singular, value-initialized iterators as an arbitrary "null
> >>>> range”.
> >>>> However, this leads to failed assertions in std:: algorithms taking
> >>>> such range.
> >>>>
> >>>> Consider the following code sample with find_if:
> >>>>
> >>>> #include 
> >>>> #include 
> >>>> #include 
> >>>>
> >>>> #ifndef __cpp_lib_null_iterators
> >>>> #warning "Not standard compliant"
> >>>> #endif
> >>>>
> >>>> int main()
> >>>> {
> >>>> std::multimap::iterator it1{};
> >>>> std::multimap::iterator it2{};
> >>>>
> >>>> (void) (it1==it2); // OK
> >>>> (void) std::find_if(
> >>>> it1, it2, [](const auto& el) { return el.second == 8;});
> >>>> }
> >>>>
> >>>> Compiled with -std=c++20 and -D_GLIBCXX_DEBUG it produces the
> >>>> warning "Not standard compliant"
> >>>> and the execution results in the following assert failure:
> >>>>
> >>>>
> /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/stl_algo.h:3875:
> >>>>
> >>>> In function:
> >>>> constexpr _IIter std::find_if(_IIter, _IIter, _Predicate) [with
> >>>> _IIter =
> >>>> gnu_debug::_Safe_iterator<_Rb_tree_iterator >,
> >>>> debug::multimap, bidirectional_iterator_tag>;
> >>>> _Predicate =
> >>>> main()::]
> >>>>
> >>>> The question is though: is it by design, or is it just a mere
> >>>> oversight? The warning actually suggest the first option.
> >>>> If it is an intentional design choice, could you provide some
> >>>> rationale behind it, please?
> >>>>
> >>>>
> >>>> The macro was not defined because the C++14 rule wasn't implemented
> >>>> for debug mode, but that should have been fixed for GCC 11, according
> >>>> to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98466 and
> >>>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70303
> >>>> So we should be able to define macro now, except maybe it wasn't fixed
> >>>> for the RB tree containers.
> >>>>
> >>>>
> >>>>
> >>>> Just to make sure there are no misunderstandings: comparison via 

[PATCH] doc: Improve punctuation and grammar in -fdiagnostics-format docs

2024-03-15 Thread Jonathan Wakely
OK for trunk?

-- >8 --

The hyphen can be misunderstood to mean "emitted to -" i.e. stdout.
Refer to both forms by name, rather than using "the former" for one and
referring to the other by name.

gcc/ChangeLog:

* doc/invoke.texi (Diagnostic Message Formatting Options):
Replace hyphen with a new sentence. Replace "the former" with
the actual value.
---
 gcc/doc/invoke.texi | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 85c938d4a14..d850b5fcdcc 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -5737,8 +5737,9 @@ named @file{@var{source}.sarif}, respectively.
 
 The @samp{json} format is a synonym for @samp{json-stderr}.
 The @samp{json-stderr} and @samp{json-file} formats are identical, apart from
-where the JSON is emitted to - with the former, the JSON is emitted to stderr,
-whereas with @samp{json-file} it is written to @file{@var{source}.gcc.json}.
+where the JSON is emitted to.  With @samp{json-stderr}, the JSON is emitted
+to stderr, whereas with @samp{json-file} it is written to
+@file{@var{source}.gcc.json}.
 
 The emitted JSON consists of a top-level JSON array containing JSON objects
 representing the diagnostics.
-- 
2.44.0



[committed] libstdc++: Fix std::format("{}", negative_integer) [PR114325]

2024-03-14 Thread Jonathan Wakely
Tested aarch64-linux. Pushed to trunk.

-- >8 --

The fast path for "{}" format strings has a bug for negative integers
where the length passed to std::to_chars is too long.

libstdc++-v3/ChangeLog:

PR libstdc++/114325
* include/std/format (_Scanner::_M_scan): Pass correct length to
__to_chars_10_impl.
* testsuite/std/format/functions/format.cc: Check negative
integers with empty format-spec.
---
 libstdc++-v3/include/std/format   | 7 ---
 libstdc++-v3/testsuite/std/format/functions/format.cc | 5 +
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index 1e839e88db4..613016d1a10 100644
--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -4091,6 +4091,7 @@ namespace __format
__sink_out = __sink.out();
 
   if constexpr (is_same_v<_CharT, char>)
+   // Fast path for "{}" format strings and simple format arg types.
if (__fmt.size() == 2 && __fmt[0] == '{' && __fmt[1] == '}')
  {
bool __done = false;
@@ -4124,14 +4125,14 @@ namespace __format
__uval = make_unsigned_t<_Tp>(~__arg) + 1u;
  else
__uval = __arg;
- const auto __n = __detail::__to_chars_len(__uval) + __neg;
- if (auto __res = __sink_out._M_reserve(__n))
+ const auto __n = __detail::__to_chars_len(__uval);
+ if (auto __res = __sink_out._M_reserve(__n + __neg))
{
  auto __ptr = __res.get();
  *__ptr = '-';
  __detail::__to_chars_10_impl(__ptr + (int)__neg, __n,
   __uval);
- __res._M_bump(__n);
+ __res._M_bump(__n + __neg);
  __done = true;
}
}
diff --git a/libstdc++-v3/testsuite/std/format/functions/format.cc 
b/libstdc++-v3/testsuite/std/format/functions/format.cc
index a27fbe74631..4499397aaf9 100644
--- a/libstdc++-v3/testsuite/std/format/functions/format.cc
+++ b/libstdc++-v3/testsuite/std/format/functions/format.cc
@@ -157,6 +157,11 @@ test_std_examples()
 
 // Restore
 std::locale::global(std::locale::classic());
+
+string s5 = format("{}", -100); // PR libstdc++/114325
+VERIFY(s5 == "-100");
+string s6 = format("{:d} {:d}", -123, 999);
+VERIFY(s6 == "-123 999");
   }
 }
 
-- 
2.44.0



[committed] libstdc++: Add nodiscard in

2024-03-14 Thread Jonathan Wakely
Tested aarch64-linux and x86_64-linux. Pushed to trunk.

I forgot to update the commit log to remove the speculation, because
Stephan Lavavej confirmed that MSVC doesn't mark those functions
nodiscard because it would result in too many false positives. Although
it might find some real bugs, it would also warn about a lot of
perfectly correct code.

-- >8 --

Add the [[nodiscard]] attribute to several functions in .
These all have no side effects and are only called for their return
value (e.g. std::count) or produce a result that must not be discarded
for correctness (e.g. std::remove).

I was intending to add the attribute to a number of other functions like
std::copy_if, std::unique_copy, std::set_union, and std::set_difference.
I stopped when I noticed that MSVC doesn't use it on those functions,
which I suspect is because they're often used with an insert iterator
(e.g. std::back_insert_iterator). In that case it doesn't matter if
you discard the result, because you have the container to tell you how
many elements were copied to the output range.

libstdc++-v3/ChangeLog:

* include/bits/stl_algo.h (find_end, all_of, none_of, any_of)
(find_if_not, is_partitioned, partition_point, remove)
(remove_if, unique, lower_bound, upper_bound, equal_range)
(binary_search, includes, is_sorted, is_sorted_until, minmax)
(minmax_element, is_permutation, clamp, find_if, find_first_of)
(adjacent_find, count, count_if, search, search_n, min_element)
(max_element): Add nodiscard attribute.
* include/bits/stl_algobase.h (min, max, lower_bound, equal)
(lexicographical_compare, lexicographical_compare_three_way)
(mismatch): Likewise.
* include/bits/stl_heap.h (is_heap, is_heap_until): Likewise.
* testsuite/25_algorithms/equal/debug/1_neg.cc: Add dg-warning.
* testsuite/25_algorithms/equal/debug/2_neg.cc: Likewise.
* testsuite/25_algorithms/equal/debug/3_neg.cc: Likewise.
* testsuite/25_algorithms/find_first_of/concept_check_1.cc:
Likewise.
* testsuite/25_algorithms/is_permutation/2.cc: Likewise.
* testsuite/25_algorithms/lexicographical_compare/71545.cc:
Likewise.
* testsuite/25_algorithms/lower_bound/33613.cc: Likewise.
* testsuite/25_algorithms/lower_bound/debug/irreflexive.cc:
Likewise.
* testsuite/25_algorithms/lower_bound/debug/partitioned_neg.cc:
Likewise.
* testsuite/25_algorithms/lower_bound/debug/partitioned_pred_neg.cc:
Likewise.
* testsuite/25_algorithms/minmax/3.cc: Likewise.
* testsuite/25_algorithms/search/78346.cc: Likewise.
* testsuite/25_algorithms/search_n/58358.cc: Likewise.
* testsuite/25_algorithms/unique/1.cc: Likewise.
* testsuite/25_algorithms/unique/11480.cc: Likewise.
* testsuite/25_algorithms/upper_bound/33613.cc: Likewise.
* testsuite/25_algorithms/upper_bound/debug/partitioned_neg.cc:
Likewise.
* testsuite/25_algorithms/upper_bound/debug/partitioned_pred_neg.cc:
Likewise.
* testsuite/ext/concept_checks.cc: Likewise.
* testsuite/ext/is_heap/47709.cc: Likewise.
* testsuite/ext/is_sorted/cxx0x.cc: Likewise.
---
 libstdc++-v3/include/bits/stl_algo.h  | 102 +-
 libstdc++-v3/include/bits/stl_algobase.h  |  32 +++---
 libstdc++-v3/include/bits/stl_heap.h  |   8 +-
 .../25_algorithms/equal/debug/1_neg.cc|   1 +
 .../25_algorithms/equal/debug/2_neg.cc|   1 +
 .../25_algorithms/equal/debug/3_neg.cc|   1 +
 .../find_first_of/concept_check_1.cc  |   1 +
 .../25_algorithms/is_permutation/2.cc |   1 +
 .../lexicographical_compare/71545.cc  |   1 +
 .../25_algorithms/lower_bound/33613.cc|   1 +
 .../lower_bound/debug/irreflexive.cc  |   1 +
 .../lower_bound/debug/partitioned_neg.cc  |   1 +
 .../lower_bound/debug/partitioned_pred_neg.cc |   1 +
 .../testsuite/25_algorithms/minmax/3.cc   |   1 +
 .../testsuite/25_algorithms/search/78346.cc   |   1 +
 .../testsuite/25_algorithms/search_n/58358.cc |   1 +
 .../testsuite/25_algorithms/unique/1.cc   |   1 +
 .../testsuite/25_algorithms/unique/11480.cc   |   2 +-
 .../25_algorithms/upper_bound/33613.cc|   1 +
 .../upper_bound/debug/partitioned_neg.cc  |   1 +
 .../upper_bound/debug/partitioned_pred_neg.cc |   1 +
 libstdc++-v3/testsuite/ext/concept_checks.cc  |   4 +
 libstdc++-v3/testsuite/ext/is_heap/47709.cc   |   1 +
 libstdc++-v3/testsuite/ext/is_sorted/cxx0x.cc |   1 +
 24 files changed, 95 insertions(+), 72 deletions(-)

diff --git a/libstdc++-v3/include/bits/stl_algo.h 
b/libstdc++-v3/include/bits/stl_algo.h
index 7a0cf6b6737..1a996aa61da 100644
--- a/libstdc++-v3/include/bits/stl_algo.h
+++ b/libstdc++-v3/include/bits/stl_algo.h
@@ -320,7 +320,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  [__first1,__last1-(__last2-__first2))
   

[PATCH] libstdc++: Suppress deprecation messages from [PR101228]

2024-03-14 Thread Jonathan Wakely
Should we do this to silence the deprecation messages from the TBB
headers we include?

-- >8 --

libstdc++-v3/ChangeLog:

PR libstdc++/101228
* include/pstl/parallel_backend_tbb.h 
(TBB_SUPPRESS_DEPRECATED_MESSAGES):
Define before including  then undef afterwards.
---
 libstdc++-v3/include/pstl/parallel_backend_tbb.h | 10 ++
 1 file changed, 10 insertions(+)

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



Re: [PATCH] libstdc++: atomic: Add missing clear_padding in __atomic_float constructor

2024-03-14 Thread Jonathan Wakely
On Fri, 16 Feb 2024 at 15:15, Jonathan Wakely wrote:
>
> On Fri, 16 Feb 2024 at 14:10, Jakub Jelinek wrote:
> >
> > On Fri, Feb 16, 2024 at 01:51:54PM +0000, Jonathan Wakely wrote:
> > > Ah, although __atomic_compare_exchange only takes pointers, the
> > > compiler replaces that with a call to __atomic_compare_exchange_n
> > > which takes the newval by value, which presumably uses an 80-bit FP
> > > register and so the padding bits become indeterminate again.
> >
> > __atomic_compare_exchange_n only works with integers, so I guess
> > it is doing VIEW_CONVERT_EXPR (aka union-style type punning) on the
> > argument.
> >
> > Do you have preprocessed source for the testcase?
>
> Sent offlist.

Jakub fixed the compiler, so I've pushed the attached patch now.

Tested x86_64-linux.
commit 0adc8c5f146b108f99c4df09e43276e3a2419262
Author: xndcn 
Date:   Fri Feb 16 11:00:13 2024

libstdc++: Add missing clear_padding in __atomic_float constructor

For 80-bit long double we need to clear the padding bits on
construction.

libstdc++-v3/ChangeLog:

* include/bits/atomic_base.h (__atomic_float::__atomic_float(Fp)):
Clear padding.
* testsuite/29_atomics/atomic_float/compare_exchange_padding.cc:
New test.

Signed-off-by: xndcn 

Reviewed-by: Jonathan Wakely 

diff --git a/libstdc++-v3/include/bits/atomic_base.h 
b/libstdc++-v3/include/bits/atomic_base.h
index b857b441169..dd360302f80 100644
--- a/libstdc++-v3/include/bits/atomic_base.h
+++ b/libstdc++-v3/include/bits/atomic_base.h
@@ -1283,7 +1283,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   constexpr
   __atomic_float(_Fp __t) : _M_fp(__t)
-  { }
+  { __atomic_impl::__clear_padding(_M_fp); }
 
   __atomic_float(const __atomic_float&) = delete;
   __atomic_float& operator=(const __atomic_float&) = delete;
diff --git 
a/libstdc++-v3/testsuite/29_atomics/atomic_float/compare_exchange_padding.cc 
b/libstdc++-v3/testsuite/29_atomics/atomic_float/compare_exchange_padding.cc
new file mode 100644
index 000..49626ac6651
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic_float/compare_exchange_padding.cc
@@ -0,0 +1,53 @@
+// { dg-do run { target c++20 } }
+// { dg-options "-O0" }
+// { dg-additional-options "[atomic_link_flags [get_multilibs]] -latomic" }
+
+#include 
+#include 
+#include 
+#include 
+
+template
+void __attribute__((noinline,noipa))
+fill_padding(T& f)
+{
+  T mask;
+  std::memset(, 0xff, sizeof(T));
+  __builtin_clear_padding();
+  unsigned char* ptr_f = (unsigned char*)
+  unsigned char* ptr_mask = (unsigned char*)
+  for (unsigned i = 0; i < sizeof(T); i++)
+  {
+if (ptr_mask[i] == 0x00)
+{
+  ptr_f[i] = 0xff;
+}
+  }
+}
+
+void
+test01()
+{
+  // test for long double with padding (float80)
+  if constexpr (std::numeric_limits::digits == 64)
+  {
+long double f = 0.5f; // long double has padding bits on x86
+fill_padding(f);
+std::atomic as{ f }; // padding cleared on constructor
+long double t = 1.5;
+
+as.fetch_add(t);
+long double s = f + t;
+t = as.load();
+VERIFY(s == t); // padding ignored on comparison
+fill_padding(s);
+VERIFY(as.compare_exchange_weak(s, f)); // padding cleared on cmpexchg
+fill_padding(f);
+VERIFY(as.compare_exchange_strong(f, t)); // padding cleared on cmpexchg
+  }
+}
+
+int main()
+{
+  test01();
+}


[committed] libstdc++: Correct notes about std::call_once in manual [PR66146]

2024-03-14 Thread Jonathan Wakely
Pushed to trunk. I should backport this too.

-- >8 --

The bug with exceptions thrown during a std::call_once call affects all
targets, so fix the docs that say it only affects non-Linux targets.

libstdc++-v3/ChangeLog:

PR libstdc++/66146
* doc/xml/manual/status_cxx2011.xml: Remove mention of Linux in
note about std::call_once.
* doc/xml/manual/status_cxx2014.xml: Likewise.
* doc/xml/manual/status_cxx2017.xml: Likewise.
* doc/html/manual/status.html: Regenerate.
---
 libstdc++-v3/doc/html/manual/status.html   | 6 +++---
 libstdc++-v3/doc/xml/manual/status_cxx2011.xml | 2 +-
 libstdc++-v3/doc/xml/manual/status_cxx2014.xml | 2 +-
 libstdc++-v3/doc/xml/manual/status_cxx2017.xml | 2 +-
 4 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/libstdc++-v3/doc/xml/manual/status_cxx2011.xml 
b/libstdc++-v3/doc/xml/manual/status_cxx2011.xml
index 1eeb2d1ccd7..7f589ad7f7a 100644
--- a/libstdc++-v3/doc/xml/manual/status_cxx2011.xml
+++ b/libstdc++-v3/doc/xml/manual/status_cxx2011.xml
@@ -2404,7 +2404,7 @@ particular release.
   30.4.4.2
   Function call_once
   Y
-  Exception support is broken on non-Linux targets.
+  Exception support is broken.
See http://www.w3.org/1999/xlink;
xlink:href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66146;>PR
66146.
diff --git a/libstdc++-v3/doc/xml/manual/status_cxx2014.xml 
b/libstdc++-v3/doc/xml/manual/status_cxx2014.xml
index 807cea57d12..518a8973f72 100644
--- a/libstdc++-v3/doc/xml/manual/status_cxx2014.xml
+++ b/libstdc++-v3/doc/xml/manual/status_cxx2014.xml
@@ -1390,7 +1390,7 @@ not in any particular release.
   30.4.4.2
   Function call_once
   Broken
-  Exception support is broken on non-Linux targets.
+  Exception support is broken.
See http://www.w3.org/1999/xlink;
xlink:href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66146;>PR
66146.
diff --git a/libstdc++-v3/doc/xml/manual/status_cxx2017.xml 
b/libstdc++-v3/doc/xml/manual/status_cxx2017.xml
index bea6db929c6..144b9909fac 100644
--- a/libstdc++-v3/doc/xml/manual/status_cxx2017.xml
+++ b/libstdc++-v3/doc/xml/manual/status_cxx2017.xml
@@ -2505,7 +2505,7 @@ since C++14 and the implementation is complete.
   33.4.6.2
   Function call_once
   Y
-  Exception support is broken on non-Linux targets.
+  Exception support is broken.
See http://www.w3.org/1999/xlink;
xlink:href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66146;>PR
66146.
-- 
2.44.0



[committed] libstdc++: Update C++23 status in the manual

2024-03-14 Thread Jonathan Wakely
I think we have all C++23 changes in this table now. At some point soon
we should replace the C++20 table of papers with the C++20 table of
contents, as we do for the other standards.

Pushed to trunk.

-- >8 --

libstdc++-v3/ChangeLog:

* doc/xml/manual/status_cxx2023.xml: Update C++23 status table.
* doc/html/manual/status.html: Regenerate.
* include/bits/version.def: Fix typo in comment.
---
 libstdc++-v3/doc/html/manual/status.html  | 146 +++--
 .../doc/xml/manual/status_cxx2023.xml | 295 +++---
 libstdc++-v3/include/bits/version.def |   2 +-
 3 files changed, 376 insertions(+), 67 deletions(-)

diff --git a/libstdc++-v3/doc/xml/manual/status_cxx2023.xml 
b/libstdc++-v3/doc/xml/manual/status_cxx2023.xml
index 4bf22f00bce..9b870d1dbdf 100644
--- a/libstdc++-v3/doc/xml/manual/status_cxx2023.xml
+++ b/libstdc++-v3/doc/xml/manual/status_cxx2023.xml
@@ -312,15 +312,32 @@ or any notes about the implementation.
 
 
 
-  
+  
ranges::to 
   
 http://www.w3.org/1999/xlink; 
xlink:href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1206r7.pdf;>
 P1206R7
 
   
+   14.1 (ranges::to function) 
+  
+   __cpp_lib_containers_ranges = 202202L,
+   __cpp_lib_ranges_to_container = 202202L
+  
+
+
+
+  
+   Ranges iterators as inputs to non-Ranges algorithms 
+  
+http://www.w3.org/1999/xlink; 
xlink:href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2408r5.html;>
+P2408R5
+
+  

-   __cpp_lib_ranges_to_container = 202202L 
+  
+   __cpp_lib_algorithm_iterator_requirements = 202207L
+  
 
 
 
@@ -377,6 +394,18 @@ or any notes about the implementation.
__cpp_lib_ranges_contains = 202207L 
 
 
+
+  
+   Making multi-param constructors of views explicit 
+  
+http://www.w3.org/1999/xlink; 
xlink:href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2711r1.html;>
+P2711R1
+
+  
+   
+  
+
+
 
ranges::fold 
   
@@ -388,6 +417,18 @@ or any notes about the implementation.
__cpp_lib_ranges_fold = 202207L 
 
 
+
+  
+   Relaxing Ranges Just A Smidge
+  
+http://www.w3.org/1999/xlink; 
xlink:href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2609r3.html;>
+P2609R3
+
+  
+   
+   __cpp_lib_ranges = 202302L 
+
+
 
   
 Compile-time programming
@@ -484,65 +525,73 @@ or any notes about the implementation.
 
 
 
-  
A type trait to detect reference binding to temporary 
   
 http://www.w3.org/1999/xlink; 
xlink:href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2255r2.html;>
 P2255R2
 
   
-   13.1 (missing changes to std::tuple 

+  
+   
+ 13.1 (missing changes to std::tuple) 

+ 14.1 (complete) 
+
+  
__cpp_lib_reference_from_temporary = 202202L 

 
 
 
-  
-Strings and text
+  
+  
+Move-only types for equality_comparable_with, totally_ordered_with,
+   and three_way_comparable_with
   
+  
+http://www.w3.org/1999/xlink; 
xlink:href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2404r3.pdf;>
+P2404R3
+
+  
+   
+   __cpp_lib_concepts = 202207L 
 
 
 
-   string contains function 
+  
+   A trait for implicit lifetime types 
   
-http://www.w3.org/1999/xlink; 
xlink:href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1679r3.html;>
-P1679R3
+http://www.w3.org/1999/xlink; 
xlink:href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2674r1.pdf;>
+P2674R1
 
   
-   11.1 
-   __cpp_lib_string_contains = 202011L 
+   
+   __cpp_lib_is_implicit_lifetime = 202302L 

 
 
 
-   Prohibit std::basic_string and std::basic_string_view 
construction from nullptr 
+  
   
-http://www.w3.org/1999/xlink; 
xlink:href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2166r1.html;>
-P2166R1
+   common_reference_t of reference_wrapper
+   Should Be a Reference Type
+  
+  
+http://www.w3.org/1999/xlink; 
xlink:href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2655r3.html;>
+P2655R3
 
   
-   12.1 
-  
+   
+   __cpp_lib_common_reference = 202302L 
 
 
 
-   basic_string::resize_and_overwrite 
+  
+   Deprecate numeric_limits::has_denorm 
   
-http://www.w3.org/1999/xlink; 
xlink:href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1072r10.html;>
-P1072R10
+http://www.w3.org/1999/xlink; 

[committed] libstdc++: Move test error_category to global scope

2024-03-13 Thread Jonathan Wakely
Tested with GDB 14.1 on x86_64-linux. I'll backport this too.

-- >8 --

A recent GDB change causes this test to fail due to missing RTTI for the
custom_cast type. This is presumably because the custom_cat type was
defined as a local class, so has no linkage. Moving it to local scope
seems to fix the test regressions, and probably makes the test more
realistic as a local class with no linkage isn't practical to use as an
error category that almost certainly needs to be referred to in other
scopes.

libstdc++-v3/ChangeLog:

* testsuite/libstdc++-prettyprinters/cxx11.cc: Move custom_cat
to namespace scope.
---
 .../testsuite/libstdc++-prettyprinters/cxx11.cc| 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc 
b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
index f867ea18306..2f75d12703c 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
@@ -63,6 +63,11 @@ struct datum
 
 std::unique_ptr global;
 
+struct custom_cat : std::error_category {
+  const char* name() const noexcept { return "miaow"; }
+  std::string message(int) const { return ""; }
+};
+
 int
 main()
 {
@@ -179,10 +184,7 @@ main()
   std::error_condition ecinval = 
std::make_error_condition(std::errc::invalid_argument);
   // { dg-final { note-test ecinval {std::error_condition = {"generic": 
EINVAL}} } }
 
-  struct custom_cat : std::error_category {
-const char* name() const noexcept { return "miaow"; }
-std::string message(int) const { return ""; }
-  } cat;
+  custom_cat cat;
   std::error_code emiaow(42, cat);
   // { dg-final { note-test emiaow {std::error_code = {custom_cat: 42}} } }
   std::error_condition ecmiaow(42, cat);
-- 
2.44.0



[committed] libstdc++: Improve documentation on debugging with libstdc++

2024-03-13 Thread Jonathan Wakely
Pushed to trunk.

-- >8 --

libstdc++-v3/ChangeLog:

* doc/xml/manual/debug.xml: Improve docs on debug builds and
using ASan. Mention _GLIBCXX_ASSERTIONS. Reorder sections to put
the most relevant ones first.
* doc/xml/manual/using.xml: Add comma.
* doc/html/*: Regenerate.
---
 libstdc++-v3/doc/html/index.html  |  2 +-
 libstdc++-v3/doc/html/manual/debug.html   | 75 +--
 .../doc/html/manual/ext_compile_checks.html   | 18 ++--
 libstdc++-v3/doc/html/manual/index.html   |  2 +-
 libstdc++-v3/doc/html/manual/intro.html   |  2 +-
 libstdc++-v3/doc/html/manual/using.html   |  2 +-
 .../doc/html/manual/using_macros.html |  2 +-
 libstdc++-v3/doc/xml/manual/debug.xml | 95 +++
 libstdc++-v3/doc/xml/manual/using.xml |  2 +-
 9 files changed, 120 insertions(+), 80 deletions(-)

diff --git a/libstdc++-v3/doc/xml/manual/debug.xml 
b/libstdc++-v3/doc/xml/manual/debug.xml
index 7f6d0876fc6..23dbae5e521 100644
--- a/libstdc++-v3/doc/xml/manual/debug.xml
+++ b/libstdc++-v3/doc/xml/manual/debug.xml
@@ -30,7 +30,7 @@
 flags can be varied to change debugging characteristics. For
 instance, turning off all optimization via the -g -O0
 -fno-inline flags will disable inlining and optimizations,
-and add debugging information, so that stepping through all functions,
+and include debugging information, so that stepping through all functions,
 (including inlined constructors and destructors) is possible. In
 addition, -fno-eliminate-unused-debug-types can be
 used when additional debug information, such as nested class info,
@@ -55,41 +55,30 @@
 
 
 
-Debug Versions of Library Binary 
Files
-
+Debug Mode
 
 
-  If you would like debug symbols in libstdc++, there are two ways to
-  build libstdc++ with debug flags. The first is to create a separate
-  debug build by running make from the top-level of a tree
-  freshly-configured with
-
-
- --enable-libstdcxx-debug
-
-and perhaps
-
- --enable-libstdcxx-debug-flags='...'
-
-
-  Both the normal build and the debug build will persist, without
-  having to specify CXXFLAGS, and the debug library will
-  be installed in a separate directory tree, in 
(prefix)/lib/debug.
-  For more information, look at the
-  configuration section.
+  The Debug Mode
+  has compile and run-time checks for many containers.
 
 
 
-  A second approach is to use the configuration flags
+  There are also lightweight assertions for checking function preconditions,
+  such as checking for out-of-bounds indices when accessing a
+  std::vector. These can be enabled without using
+  the full Debug Mode, by using -D_GLIBCXX_ASSERTIONS
+  (see ).
 
-
- make CXXFLAGS='-g3 -fno-inline -O0' all
-
+
+
+
+Tracking uncaught 
exceptions
 
 
-  This quick and dirty approach is often sufficient for quick
-  debugging tasks, when you cannot or don't want to recompile your
-  application to use the debug 
mode.
+  The verbose
+  termination handler gives information about uncaught
+  exceptions which kill the program.
+
 
 
 Memory Leak Hunting
@@ -99,6 +88,13 @@
   which is enabled by the -fsanitize=address option.
 
 
+
+  The std::vector implementation has additional
+  instrumentation to work with AddressSanitizer, but this has to be enabled
+  explicitly by using -D_GLIBCXX_SANITIZE_VECTOR
+  (see ).
+
+
 
   There are also various third party memory tracing and debug utilities
   that can be used to provide detailed memory allocation information
@@ -331,21 +327,44 @@
 
 
 
-Tracking uncaught 
exceptions
+Debug Versions of Library Binary 
Files
 
 
-  The verbose
-  termination handler gives information about uncaught
-  exceptions which kill the program.
+  As described above, libstdc++ is built with debug symbols enabled by default,
+  but because it's also built with optimizations the code can be hard to
+  follow when stepping into the library in a debugger.
 
+
+
+  If you would like to debug libstdc++.so itself,
+  there are two ways to build an unoptimized libstdc++ with debug flags.
+  The first is to create a separate debug build by running make from the
+  top-level of a tree freshly-configured with
+
+
+ --enable-libstdcxx-debug
+
+and perhaps
+
+ --enable-libstdcxx-debug-flags='...'
+
+
+  Both the normal build and the debug build will persist, without
+  having to specify CXXFLAGS, and the debug library will
+  be installed in a separate directory tree, in 
(prefix)/lib/debug.
+  For more information, look at the
+  configuration section.
+
+
+
+  A second approach is to use the configuration flags
+
+
+ make CXXFLAGS='-g3 -fno-inline -O0' all
+
+
 
 
-Debug Mode
-
-   The Debug Mode
-  has compile and run-time checks for many containers.
-  
-
 
 Compile Time 
Checking
 
diff --git a/libstdc++-v3/doc/xml/manual/using.xml 
b/libstdc++-v3/doc/xml/manual/using.xml
index b3b0c368e44..8ac7e74034c 100644
--- 

Re: [PATCH] libstdc++: Document that _GLIBCXX_CONCEPT_CHECKS might be removed in future

2024-03-13 Thread Jonathan Wakely
On Thu, 7 Mar 2024 at 12:07, Jonathan Wakely wrote:
>
> Any objection to this update to make the docs reflect reality?

Pushed to trunk now.


>
> -- >8 --
>
> The macro-based concept checks are unmaintained and do not support C++11
> or later, so reject valid code. If nobody plans to update them we should
> consider removing them. Alternatively, we could ignore the macro for
> C++11 and later, so they have no effect and don't reject valid code.
>
> libstdc++-v3/ChangeLog:
>
> * doc/xml/manual/debug.xml: Document that concept checking might
> be removed in future.
> * doc/xml/manual/extensions.xml: Likewise.
> ---
>  libstdc++-v3/doc/xml/manual/debug.xml  |  2 ++
>  libstdc++-v3/doc/xml/manual/extensions.xml | 18 --
>  2 files changed, 14 insertions(+), 6 deletions(-)
>
> diff --git a/libstdc++-v3/doc/xml/manual/debug.xml 
> b/libstdc++-v3/doc/xml/manual/debug.xml
> index 42d4d32aa29..7f6d0876fc6 100644
> --- a/libstdc++-v3/doc/xml/manual/debug.xml
> +++ b/libstdc++-v3/doc/xml/manual/debug.xml
> @@ -351,6 +351,8 @@
>
> The Compile-Time
>Checks extension has compile-time checks for many algorithms.
> +  These checks were designed for C++98 and have not been updated to work
> +  with C++11 and later standards. They might be removed at a future date.
>
>  
>
> diff --git a/libstdc++-v3/doc/xml/manual/extensions.xml 
> b/libstdc++-v3/doc/xml/manual/extensions.xml
> index d4fe2f509d4..490a50cc331 100644
> --- a/libstdc++-v3/doc/xml/manual/extensions.xml
> +++ b/libstdc++-v3/doc/xml/manual/extensions.xml
> @@ -77,8 +77,7 @@ extensions, be aware of two things:
>object file.  The checks are also cleaner and easier to read and
>understand.
> 
> -   They are off by default for all versions of GCC from 3.0 to 3.4 (the
> -  latest release at the time of writing).
> +   They are off by default for all GCC 3.0 and all later versions.
>They can be enabled at configure time with
> linkend="manual.intro.setup.configure">--enable-concept-checks.
>You can enable them on a per-translation-unit basis with
> @@ -89,10 +88,17 @@ extensions, be aware of two things:
> 
>
> Please note that the concept checks only validate the requirements
> -   of the old C++03 standard. C++11 was expected to have first-class
> -   support for template parameter constraints based on concepts in the core
> -   language. This would have obviated the need for the library-simulated 
> concept
> -   checking described above, but was not part of C++11.
> +   of the old C++03 standard and reject some valid code that meets the 
> relaxed
> +   requirements of C++11 and later standards.
> +   C++11 was expected to have first-class support for template parameter
> +   constraints based on concepts in the core language.
> +   This would have obviated the need for the library-simulated concept 
> checking
> +   described above, but was not part of C++11.
> +   C++20 adds a different model of concepts, which is now used to constrain
> +   some new parts of the C++20 library, e.g. the
> +   ranges header and the new overloads in the
> +   algorithm header for working with ranges.
> +   The old library-simulated concept checks might be removed at a future 
> date.
> 
>
>  
> --
> 2.43.2
>



[wwwdocs] Reverse development timeline graph

2024-03-13 Thread Jonathan Wakely
Every year I have to scroll down further and further to the useful part,
and I'm getting too old to spend my time doing that! :)

I suggested this on IRC and iains agreed. What do others think?

-- >8 --

This seems more useful with the recent history first.
---
 htdocs/develop.html | 819 ++--
 1 file changed, 411 insertions(+), 408 deletions(-)

diff --git a/htdocs/develop.html b/htdocs/develop.html
index 702256cf..f741bd4a 100644
--- a/htdocs/develop.html
+++ b/htdocs/develop.html
@@ -298,421 +298,424 @@ number carried little to no useful information.
 
 Release Timeline
 
-Here is a history of recent and a tentative timeline of upcoming
+Here is a history of releases and a tentative timeline of upcoming
 stages of development, branch points, and releases:
 
 
 
-  ... former releases ...
-   |
-   +-- GCC 3.0 branch created --+
-   |  (Feb 12 2001)  \
-   |  v
-   v   GCC 3.0 release (Jun 18 2001)
-  New development plan announced\
-   |  (Jul 18 2001)  v
-   |   GCC 3.0.1 release (Aug 20 2001)
-   |   \
-   vv
-  GCC 3.1 Stage 1 (ended Oct 15 2001)  GCC 3.0.2 release (Oct 25 2001)
-   |  \
-   v   v
-  GCC 3.1 Stage 2 (ended Dec 19 2001)  GCC 3.0.3 release (Dec 20 2001)
-   | \
-   v  v
-  GCC 3.1 Stage 3 (ended Feb 26 2002)  GCC 3.0.4 release (Feb 20 2002)
-   |
-   +-- GCC 3.1 branch created --+
-   | \
-   |  v
-   v   GCC 3.1 release (May 15 2002)
-  GCC 3.2 Stage 1 (ended Jun 22 2002)   \
-   | v
-   |   GCC 3.1.1 release (Jul 25 2002)
-   |   \
-   vv
-  New development plan announced   Branch renamed to GCC 3.2 to
-   |  (Jul 14 2002)accommodate for C++ ABI fixes
-   |   (C++ binary incompatible with
-   |   GCC 3.1, see release info)
-   | \
-   |  v
-   |   GCC 3.2 release (Aug 14 2002)
-   |\
-   | v
-   |   GCC 3.2.1 release (Nov 19 2002)
-   |   \
-   |v
-   |   GCC 3.2.2 release (Feb 05 2003)
-   |  \
-   |   v
-   |   GCC 3.2.3 release (April 22 2003)
-   v
-  GCC 3.3 Stage 2 (ends Aug 15 2002)
-   |
-   v
-  GCC 3.3 Stage 3 (ends Oct 15 2002)
-   |
-   +-- GCC 3.3 branch created --+
-   |(Dec 14 2002)\
-   |  v
-   |   GCC 3.3 release (May 13 2003)
-   |\
-   v v
-  GCC 3.4 Stage 1 (ends July 4 2003)   GCC 3.3.1 release (Aug 8 2003)
-   |   \
-   vv
-  GCC 3.4 Stage 2 (ends October 15 2003)   GCC 3.3.2 release (Oct 17 2003)
-   |  \
-   v   v
-  GCC 3.4 Stage 3  GCC 3.3.3 release (Feb 14 2004)
-   | \
-   |  v
-   |   GCC 3.3.4 release (May 31 2004)
-   |\
-   | v
-   |   GCC 3.3.5 release (Sep 30 2004)
-   |   \
-   |v
-   |   GCC 3.3.6 release (May 03 2005)
-   |
-   +-- GCC 3.4 branch created --+
-   |(Jan 16 2004)\
-   |  v
-  Tree SSA infrastructure  GCC 3.4.0 release (Apr 18 

Re: [PATCH v1] libstdc++: Optimize removal from unique assoc containers [PR112934]

2024-03-13 Thread Jonathan Wakely
On Mon, 11 Mar 2024 at 23:36, Barnabás Pőcze  wrote:
>
> Previously, calling erase(key) on both std::map and std::set
> would execute that same code that std::multi{map,set} would.
> However, doing that is unnecessary because std::{map,set}
> guarantee that all elements are unique.
>
> It is reasonable to expect that erase(key) is equivalent
> or better than:
>
>   auto it = m.find(key);
>   if (it != m.end())
> m.erase(it);
>
> However, this was not the case. Fix that by adding a new
> function _Rb_tree<>::_M_erase_unique() that is essentially
> equivalent to the above snippet, and use this from both
> std::map and std::set.

Hi, this change looks reasonable, thanks for the patch. Please note
that GCC is currently in "stage 3" of its dev process so this change
would have to wait until after GCC 14 branches from trunk, due in a
few weeks.

I assume you ran the testsuite with no regressions. Do you have
benchmarks to show this making a difference?


>
> libstdc++-v3/ChangeLog:
>
> PR libstdc++/112934
> * include/bits/stl_tree.h (_Rb_tree<>::_M_erase_unique): Add.
> * include/bits/stl_map.h (map<>::erase): Use _M_erase_unique.
> * include/bits/stl_set.h (set<>::erase): Likewise.
> ---
>  libstdc++-v3/include/bits/stl_map.h  |  2 +-
>  libstdc++-v3/include/bits/stl_set.h  |  2 +-
>  libstdc++-v3/include/bits/stl_tree.h | 17 +
>  3 files changed, 19 insertions(+), 2 deletions(-)
>
> diff --git a/libstdc++-v3/include/bits/stl_map.h 
> b/libstdc++-v3/include/bits/stl_map.h
> index ad58a631af5..229643b77fd 100644
> --- a/libstdc++-v3/include/bits/stl_map.h
> +++ b/libstdc++-v3/include/bits/stl_map.h
> @@ -1115,7 +1115,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
> */
>size_type
>erase(const key_type& __x)
> -  { return _M_t.erase(__x); }
> +  { return _M_t._M_erase_unique(__x); }
>
>  #if __cplusplus >= 201103L
>// _GLIBCXX_RESOLVE_LIB_DEFECTS
> diff --git a/libstdc++-v3/include/bits/stl_set.h 
> b/libstdc++-v3/include/bits/stl_set.h
> index c0eb4dbf65f..51a1717ec62 100644
> --- a/libstdc++-v3/include/bits/stl_set.h
> +++ b/libstdc++-v3/include/bits/stl_set.h
> @@ -684,7 +684,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
> */
>size_type
>erase(const key_type& __x)
> -  { return _M_t.erase(__x); }
> +  { return _M_t._M_erase_unique(__x); }
>
>  #if __cplusplus >= 201103L
>// _GLIBCXX_RESOLVE_LIB_DEFECTS
> diff --git a/libstdc++-v3/include/bits/stl_tree.h 
> b/libstdc++-v3/include/bits/stl_tree.h
> index 6f470f04f6a..9e80d449c7e 100644
> --- a/libstdc++-v3/include/bits/stl_tree.h
> +++ b/libstdc++-v3/include/bits/stl_tree.h
> @@ -1225,6 +1225,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>size_type
>erase(const key_type& __x);
>
> +  size_type
> +  _M_erase_unique(const key_type& __x);
> +
>  #if __cplusplus >= 201103L
>// _GLIBCXX_RESOLVE_LIB_DEFECTS
>// DR 130. Associative erase should return an iterator.
> @@ -2518,6 +2521,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>return __old_size - size();
>  }
>
> +  template +  typename _Compare, typename _Alloc>
> +typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type
> +_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
> +_M_erase_unique(const _Key& __x)
> +{
> +  iterator __it = find(__x);
> +  if (__it == end())
> +   return 0;
> +
> +  _M_erase_aux(__it);
> +  return 1;
> +}
> +
>templatetypename _Compare, typename _Alloc>
>  typename _Rb_tree<_Key, _Val, _KeyOfValue,
> --
> 2.44.0
>
>



Re: [PATCH 1/2] libstdc++: Atomic wait/notify ABI stabilization

2024-03-09 Thread Jonathan Wakely
On Sat, 9 Mar 2024 at 12:18, Jonathan Wakely  wrote:

>
>
>
> +template
>> +  __wait_result_type
>> +  __wait_for(const __platform_wait_t* __addr, __wait_args __args,
>> +const chrono::duration<_Rep, _Period>& __rtime) noexcept
>> +{
>> +  if (!__rtime.count())
>> +   // no rtime supplied, just spin a bit
>> +   return __detail::__wait_impl(__addr, __args |
>> __wait_flags::__spin_only);
>>
>
> This should set __do_spin | __spin_only if the latter no longer implies
> the former.
>
>
>>
>> +enum class __wait_flags : uint32_t
>>  {
>>
>
>
>> +   __abi_version = 0,
>> +   __proxy_wait = 1,
>> +   __track_contention = 2,
>> +   __do_spin = 4,
>> +   __spin_only = 8 | __do_spin, // implies __do_spin
>>
>
> This should be just 8 and not also imply __do_spin.
>


Alternatively, we could have:

   __spin_only = 4,
   __spin_then_wait = 8,
   __do_spin = __spin_only | __spin_then_wait,

Then testing (flags & do_spin) would be true if either of the others is
set, but (flags & spin_only) would do the right thing.

But if we have spin_then_wait in the default flags, a caller that wants to
use spin_only has to clear the spin_then_wait flag, otherwise there are two
mutually exclusive flags set at once.

I think I prefer:

   __do_spin = 4,
   __spin_only = 8, // Ignored unless __do_spin is also set.

as this is simpler for callers.


Re: [PATCH 1/2] libstdc++: Atomic wait/notify ABI stabilization

2024-03-09 Thread Jonathan Wakely
On Thu, 16 Nov 2023 at 13:49, Jonathan Wakely  wrote:

> From: Thomas Rodgers 
>
> These two patches were written by Tom earlier this year, before he left
> Red Hat. We should finish reviewing them for GCC 14 (and probably squash
> them into one?)
>
> Tom, you mentioned further work that changes the __platform_wait_t* to
> uintptr_t, is that ready, or likely to be ready very soon?
>
> Tested x86_64-linux, testing underway on powerpc-aix and sparc-solaris.
>
>
> -- >8 --
>
> This represents a major refactoring of the previous atomic::wait
> and atomic::notify implementation detail. The aim of this change
> is to simplify the implementation details and position the resulting
> implementation so that much of the current header-only detail
> can be moved into the shared library, while also accounting for
> anticipated changes to wait/notify functionality for C++26.
>
> The previous implementation implemented spin logic in terms of
> the types __default_spin_policy, __timed_backoff_spin_policy, and
> the free function __atomic_spin. These are replaced in favor of
> two new free functions; __spin_impl and __spin_until_impl. These
> currently inline free functions are expected to be moved into the
> libstdc++ shared library in a future commit.
>
> The previous implementation derived untimed and timed wait
> implementation detail from __detail::__waiter_pool_base. This
> is-a relationship is removed in the new version and the previous
> implementation detail is renamed to reflect this change. The
> static _S_for member has been renamed as well to indicate that it
> returns the __waiter_pool_impl entry in the static 'side table'
> for a given awaited address.
>
> This new implementation replaces all of the non-templated waiting
> detail of __waiter_base, __waiter_pool, __waiter, __enters_wait, and
> __bare_wait with the __wait_impl free function, and the supporting
> __wait_flags enum and __wait_args struct. This currenly inline free
> function is expected to be moved into the libstdc++ shared library
> in a future commit.
>
> This new implementation replaces all of the non-templated notifying
> detail of __waiter_base, __waiter_pool, and __waiter with the
> __notify_impl free function. This currently inline free function
> is expected to be moved into the libstdc++ shared library in a
> future commit.
>
> The __atomic_wait_address template function is updated to account
> for the above changes and to support the expected C++26 change to
> pass the most recent observed value to the caller supplied predicate.
>
> A new non-templated __atomic_wait_address_v free function is added
> that only works for atomic types that operate only on __platform_wait_t
> and requires the caller to supply a memory order. This is intended
> to be the simplest code path for such types.
>
> The __atomic_wait_address_v template function is now implemented in
> terms of new __atomic_wait_address template and continues to accept
> a user supplied "value function" to retrieve the current value of
> the atomic.
>
> The __atomic_notify_address template function is updated to account
> for the above changes.
>
> The template __platform_wait_until_impl is renamed to
> __wait_clock_t. The previous __platform_wait_until template is deleted
> and the functionality previously provided is moved t the new tempalate
> function __wait_until. A similar change is made to the
> __cond_wait_until_impl/__cond_wait_until implementation.
>
> This new implementation similarly replaces all of the non-templated
> waiting detail of __timed_waiter_pool, __timed_waiter, etc. with
> the new __wait_until_impl free function. This currently inline free
> function is expected to be moved into the libstdc++ shared library
> in a future commit.
>
> This implementation replaces all templated waiting functions that
> manage clock conversion as well as relative waiting (wait_for) with
> the new template functions __wait_until and __wait_for.
>
> Similarly the previous implementation detail for the various
> __atomic_wait_address_Xxx templates is adjusted to account for the
> implementation changes outlined above.
>
> All of the "bare wait" versions of __atomic_wait_Xxx have been removed
> and replaced with a defaulted boolean __bare_wait parameter on the
> new version of these templates.
>
> libstdc++-v3/ChangeLog:
>
> * include/bits/atomic_timed_wait.h:
> (__detail::__platform_wait_until_impl): Rename to
> __platform_wait_until.
> (__detail::__platform_wait_until): Remove previous
> definition.
> (__detail::__cond_wait_until_impl): Rename to
> __cond_wait_until.
> (__detail::__cond_wait_until)

[committed] libstdc++: Do not require a time-of-day when parsing sys_days [PR114240]

2024-03-08 Thread Jonathan Wakely
Tested x86_64-linux. Pushed to trunk.

-- >8 --

When parsing a std::chrono::sys_days (or a sys_time with an even longer
period) we should not require a time-of-day to be present in the input,
because we can't represent that in the result type anyway.

Rather than trying to decide which specializations should require a
time-of-date and which should not, follow the direction of Howard
Hinnant's date library, which allows extracting a sys_time of any period
from input that only contains a date, defaulting the time-of-day part to
00:00:00. This seems consistent with the intent of the standard, which
says it's an error "If the parse fails to decode a valid date" (i.e., it
doesn't care about decoding a valid time, only a date).

libstdc++-v3/ChangeLog:

PR libstdc++/114240
* include/bits/chrono_io.h (_Parser::operator()): Assume
hours(0) for a time_point, so that a time is not required
to be present.
* testsuite/std/time/parse/114240.cc: New test.
---
 libstdc++-v3/include/bits/chrono_io.h | 12 ++-
 .../testsuite/std/time/parse/114240.cc| 36 +++
 2 files changed, 47 insertions(+), 1 deletion(-)
 create mode 100644 libstdc++-v3/testsuite/std/time/parse/114240.cc

diff --git a/libstdc++-v3/include/bits/chrono_io.h 
b/libstdc++-v3/include/bits/chrono_io.h
index eaa36b8a074..b9eb3d2be53 100644
--- a/libstdc++-v3/include/bits/chrono_io.h
+++ b/libstdc++-v3/include/bits/chrono_io.h
@@ -3157,6 +3157,16 @@ namespace __detail
  minutes __tz_offset = __bad_min;
  basic_string<_CharT, _Traits> __tz_abbr;
 
+ if ((_M_need & _ChronoParts::_TimeOfDay)
+   && (_M_need & _ChronoParts::_Year))
+   {
+ // For time_points assume "00:00:00" is implicitly present,
+ // so we don't fail to parse if it's not (PR libstdc++/114240).
+ // We will still fail to parse if there's no year+month+day.
+ __h = hours(0);
+ __parts = _ChronoParts::_TimeOfDay;
+   }
+
  // bool __is_neg = false; // TODO: how is this handled for parsing?
 
  _CharT __mod{}; // One of 'E' or 'O' or nul.
@@ -4098,7 +4108,7 @@ namespace __detail
  const bool __need_wday = _M_need & _ChronoParts::_Weekday;
 
  // Whether the caller wants _M_sys_days and _M_time.
- // Only true for time_points.
+ // Only true for durations and time_points.
  const bool __need_time = _M_need & _ChronoParts::_TimeOfDay;
 
  if (__need_wday && __wday != __bad_wday)
diff --git a/libstdc++-v3/testsuite/std/time/parse/114240.cc 
b/libstdc++-v3/testsuite/std/time/parse/114240.cc
new file mode 100644
index 000..46310efd09a
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/time/parse/114240.cc
@@ -0,0 +1,36 @@
+// { dg-do run { target c++20 } }
+
+// PR libstdc++/114240 sys_days not being parsed with only a date in the stream
+
+#include 
+#include 
+#include 
+
+template
+void
+test_parse_date_only()
+{
+  using namespace std::chrono;
+
+  using CDays = time_point;
+  CDays td;
+  std::istringstream is("2024-03-05");
+  VERIFY( is >> parse("%Y-%m-%d ", td) );
+  if constexpr (std::is_same_v)
+VERIFY( td == static_cast>(2024y/March/5) );
+  else
+  {
+auto tp = clock_cast(sys_days(2024y/March/5));
+VERIFY( td == time_point_cast(tp) );
+  }
+}
+
+int main()
+{
+  test_parse_date_only();
+  test_parse_date_only();
+  test_parse_date_only();
+  test_parse_date_only();
+  test_parse_date_only();
+  test_parse_date_only();
+}
-- 
2.43.2



[committed] libstdc++: Fix parsing of leap seconds as chrono::utc_time [PR114279]

2024-03-08 Thread Jonathan Wakely
Tested x86_64-linux. Pushed to trunk.

-- >8 --

Implementing all chrono::from_stream overloads in terms of
chrono::sys_time meant that a leap second time like 23:59:60.001 cannot
be parsed, because that cannot be represented in a sys_time.

The fix to support parsing leap seconds as utc_time is to convert the
parsed date to utc_time and then add the parsed time to that,
which allows the result to land in a leap second, rather than doing all
the arithmetic with sys_time which doesn't have leap seconds.

For local_time we also allow %S to parse a 60s value, because doing
otherwise might disallow some valid uses. We can't know all use cases
users have for treating times as local_time.

For all other clocks, we can reject times that have 60 or 60.nnn as the
seconds part, because that cannot occur in a valid UNIX, GPS, or TAI
time. Since our chrono::file_clock uses sys_time, it can't occur for
that clock either.

In order to support this a new _M_is_leap_second member is needed in the
_Parser type. This can be added at the end, where most targets currently
have padding bytes. Similar to what I did recently for formatter _Spec
structs, we can also reserve additional padding bits for future
expansion.

This also fixes bugs in the from_stream overloads for utc_time,
tai_time, gps_time, and file_time, which were not using time_point_cast
to explicitly convert to the result type. That's needed because the
result type might have lower precision than the value returned from
from_sys or from_utc, which has a precision no lower than seconds.

libstdc++-v3/ChangeLog:

PR libstdc++/114279
* include/bits/chrono_io.h (_Parser::_M_is_leap_second): New
data member.
(_Parser::_M_reserved): Reserve padding bits for future use.
(_Parser::operator()): Set _M_is_leap_second if %S reads 60s.
(from_stream): Only allow _M_is_leap_second for utc_time and
local_time. Adjust arithmetic for utc_time so that leap seconds
are preserved. Use time_point_cast to convert to a possibly
lower-precision result type.
* testsuite/std/time/parse.cc: Move to ...
* testsuite/std/time/parse/parse.cc: ... here.
* testsuite/std/time/parse/114279.cc: New test.
---
 libstdc++-v3/include/bits/chrono_io.h | 74 ---
 .../testsuite/std/time/parse/114279.cc| 53 +
 .../testsuite/std/time/{ => parse}/parse.cc   |  0
 3 files changed, 115 insertions(+), 12 deletions(-)
 create mode 100644 libstdc++-v3/testsuite/std/time/parse/114279.cc
 rename libstdc++-v3/testsuite/std/time/{ => parse}/parse.cc (100%)

diff --git a/libstdc++-v3/include/bits/chrono_io.h 
b/libstdc++-v3/include/bits/chrono_io.h
index 412e8b83fb7..eaa36b8a074 100644
--- a/libstdc++-v3/include/bits/chrono_io.h
+++ b/libstdc++-v3/include/bits/chrono_io.h
@@ -2164,6 +2164,8 @@ namespace __detail
   year_month_day _M_ymd{};
   weekday _M_wd{};
   __format::_ChronoParts _M_need;
+  unsigned _M_is_leap_second : 1 {};
+  unsigned _M_reserved : 15 {};
 
   template
basic_istream<_CharT, _Traits>&
@@ -2742,8 +2744,13 @@ namespace __detail
   __detail::_Parser_t<_Duration> __p(__need);
   if (__p(__is, __fmt, __abbrev, __offset))
{
- auto __st = __p._M_sys_days + __p._M_time - *__offset;
- __tp = chrono::time_point_cast<_Duration>(__st);
+ if (__p._M_is_leap_second)
+   __is.setstate(ios_base::failbit);
+ else
+   {
+ auto __st = __p._M_sys_days + __p._M_time - *__offset;
+ __tp = chrono::time_point_cast<_Duration>(__st);
+   }
}
   return __is;
 }
@@ -2765,9 +2772,21 @@ namespace __detail
basic_string<_CharT, _Traits, _Alloc>* __abbrev = nullptr,
minutes* __offset = nullptr)
 {
-  sys_time<_Duration> __st;
-  if (chrono::from_stream(__is, __fmt, __st, __abbrev, __offset))
-   __tp = utc_clock::from_sys(__st);
+  minutes __off{};
+  if (!__offset)
+   __offset = &__off;
+  using __format::_ChronoParts;
+  auto __need = _ChronoParts::_Year | _ChronoParts::_Month
+   | _ChronoParts::_Day | _ChronoParts::_TimeOfDay;
+  __detail::_Parser_t<_Duration> __p(__need);
+  if (__p(__is, __fmt, __abbrev, __offset))
+   {
+ // Converting to utc_time before adding _M_time is necessary for
+ // "23:59:60" to correctly produce a time within a leap second.
+ auto __ut = utc_clock::from_sys(__p._M_sys_days) + __p._M_time
+   - *__offset;
+ __tp = chrono::time_point_cast<_Duration>(__ut);
+   }
   return __is;
 }
 
@@ -2788,9 +2807,24 @@ namespace __detail
basic_string<_CharT, _Traits, _Alloc>* __abbrev = nullptr,
minutes* __offset = nullptr)
 {
-  utc_time<_Duration> __ut;
-  if (chrono::from_stream(__is, __fmt, __ut, __abbrev, __offset))
-   

[committed] libstdc++: Use std::from_chars to speed up parsing subsecond durations

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

-- >8 --

With std::from_chars we can parse subsecond durations much faster than
with std::num_get, as shown in the microbenchmarks below. We were using
std::num_get and std::numpunct in order to parse a number with the
locale's decimal point character. But we copy the chars from the input
stream into a new buffer anyway, so we can replace the locale's decimal
point with '.' in that buffer, and then we can use std::from_chars on
it.

BenchmarkTime CPU   Iterations
--
from_chars_millisec158 ns  158 ns  4524046
num_get_millisec   192 ns  192 ns  3644626
from_chars_microsec164 ns  163 ns  4330627
num_get_microsec   205 ns  205 ns  3413452
from_chars_nanosec 173 ns  173 ns  4072653
num_get_nanosec227 ns  227 ns  3105161

libstdc++-v3/ChangeLog:

* include/bits/chrono_io.h (_Parser::operator()): Use
std::from_chars to parse fractional seconds.
---
 libstdc++-v3/include/bits/chrono_io.h | 28 +--
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/libstdc++-v3/include/bits/chrono_io.h 
b/libstdc++-v3/include/bits/chrono_io.h
index b8f0657bee9..412e8b83fb7 100644
--- a/libstdc++-v3/include/bits/chrono_io.h
+++ b/libstdc++-v3/include/bits/chrono_io.h
@@ -37,6 +37,7 @@
 #include  // ostringstream
 #include  // setw, setfill
 #include 
+#include  // from_chars
 
 #include 
 
@@ -3597,13 +3598,17 @@ namespace __detail
__err |= ios_base::eofbit;
  else
{
- auto& __np = use_facet>(__loc);
- auto __dp = __np.decimal_point();
+ _CharT __dp = '.';
+ if (__loc != locale::classic())
+   {
+ auto& __np = use_facet>(__loc);
+ __dp = __np.decimal_point();
+   }
  _CharT __c = _Traits::to_char_type(__i);
  if (__c == __dp)
{
  (void) __is.get();
- __buf.put(__c);
+ __buf.put('.');
  int __prec
= hh_mm_ss<_Duration>::fractional_width;
  do
@@ -3618,14 +3623,17 @@ namespace __detail
}
}
 
- if (!__is_failed(__err))
+ if (!__is_failed(__err)) [[likely]]
{
- auto& __ng = use_facet>(__loc);
- long double __val;
- ios_base::iostate __err2{};
- __ng.get(__buf, {}, __buf, __err2, __val);
- if (__is_failed(__err2)) [[unlikely]]
-   __err |= __err2;
+ long double __val{};
+ string __str = std::move(__buf).str();
+ auto __first = __str.data();
+ auto __last = __first + __str.size();
+ using enum chars_format;
+ auto [ptr, ec] = std::from_chars(__first, __last,
+  __val, fixed);
+ if ((bool)ec || ptr != __last) [[unlikely]]
+   __err |= ios_base::failbit;
  else
{
  duration __fs(__val);
-- 
2.43.2



[committed] libstdc++: Fix parsing of fractional seconds [PR114244]

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

-- >8 --

When converting a chrono::duration to a result type with an
integer representation we should use chrono::round<_Duration> so that we
don't truncate towards zero. Rounding ensures that e.g. 0.001999s
becomes 2ms not 1ms.

We can also remove some redundant uses of chrono::duration_cast to
convert from seconds to _Duration, because the _Parser class template
requires _Duration type to be able to represent seconds without loss of
precision.

This also fixes a bug where no fractional part would be parsed for
chrono::duration because its period is ratio<1>. We should
also consider treat_as_floating_point when deciding whether to skip
reading a fractional part.

libstdc++-v3/ChangeLog:

PR libstdc++/114244
* include/bits/chrono_io.h (_Parser::operator()): Remove
redundant uses of duration_cast. Use chrono::round to convert
long double value to durations with integer representations.
Check represenation type when deciding whether to skip parsing
fractional seconds.
* testsuite/20_util/duration/114244.cc: New test.
* testsuite/20_util/duration/io.cc: Check that a floating-point
duration with ratio<1> precision can be parsed.
---
 libstdc++-v3/include/bits/chrono_io.h | 18 ++
 .../testsuite/20_util/duration/114244.cc  | 36 +++
 libstdc++-v3/testsuite/20_util/duration/io.cc | 12 +++
 3 files changed, 60 insertions(+), 6 deletions(-)
 create mode 100644 libstdc++-v3/testsuite/20_util/duration/114244.cc

diff --git a/libstdc++-v3/include/bits/chrono_io.h 
b/libstdc++-v3/include/bits/chrono_io.h
index 82f2d39ec44..b8f0657bee9 100644
--- a/libstdc++-v3/include/bits/chrono_io.h
+++ b/libstdc++-v3/include/bits/chrono_io.h
@@ -3113,6 +3113,9 @@ namespace __detail
  unsigned __num = 0; // Non-zero for N modifier.
  bool __is_flag = false; // True if we're processing a % flag.
 
+ constexpr bool __is_floating
+   = treat_as_floating_point_v;
+
  // If an out-of-range value is extracted (e.g. 61min for %M),
  // do not set failbit immediately because we might not need it
  // (e.g. parsing chrono::year doesn't care about invalid %M values).
@@ -3195,7 +3198,7 @@ namespace __detail
  __d = day(__tm.tm_mday);
  __h = hours(__tm.tm_hour);
  __min = minutes(__tm.tm_min);
- __s = duration_cast<_Duration>(seconds(__tm.tm_sec));
+ __s = seconds(__tm.tm_sec);
}
}
  __parts |= _ChronoParts::_DateTime;
@@ -3564,8 +3567,8 @@ namespace __detail
  if (!__is_failed(__err))
__s = seconds(__tm.tm_sec);
}
- else if constexpr (ratio_equal_v>)
+ else if constexpr (_Duration::period::den == 1
+  && !__is_floating)
{
  auto __val = __read_unsigned(__num ? __num : 2);
  if (0 <= __val && __val <= 59) [[likely]]
@@ -3577,7 +3580,7 @@ namespace __detail
  break;
}
}
- else
+ else // Read fractional seconds
{
  basic_stringstream<_CharT> __buf;
  auto __digit = _S_try_read_digit(__is, __err);
@@ -3626,7 +3629,10 @@ namespace __detail
  else
{
  duration __fs(__val);
- __s = duration_cast<_Duration>(__fs);
+ if constexpr (__is_floating)
+   __s = __fs;
+ else
+   __s = chrono::round<_Duration>(__fs);
}
}
}
@@ -3737,7 +3743,7 @@ namespace __detail
{
  __h = hours(__tm.tm_hour);
  __min = minutes(__tm.tm_min);
- __s = duration_cast<_Duration>(seconds(__tm.tm_sec));
+ __s = seconds(__tm.tm_sec);
}
}
  __parts |= _ChronoParts::_TimeOfDay;
diff --git a/libstdc++-v3/testsuite/20_util/duration/114244.cc 
b/libstdc++-v3/testsuite/20_util/duration/114244.cc
new file mode 100644
index 000..55a7670522a
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/duration/114244.cc
@@ -0,0 +1,36 @@
+// { dg-do run { target c++20 } }
+// { dg-timeout-factor 2 }
+// { dg-require-namedlocale "en_US.ISO8859-1" }
+
+// PR libstdc++/114244 Need to use round when parsing fractional seconds
+
+#include 
+#include 
+#include 
+
+void
+test_pr114244()
+{
+  using namespace 

[committed] libstdc++: Do not define lock-free atomic aliases if not fully lock-free [PR114103]

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

-- >8 --

The whole point of these typedefs is to guarantee lock-freedom, so if
the target has no such types, we shouldn't defined the typedefs at all.

libstdc++-v3/ChangeLog:

PR libstdc++/114103
* include/bits/version.def (atomic_lock_free_type_aliases): Add
extra_cond to check for at least one always-lock-free type.
* include/bits/version.h: Regenerate.
* include/std/atomic (atomic_signed_lock_free)
(atomic_unsigned_lock_free): Only use always-lock-free types.
* src/c++20/tzdb.cc (time_zone::_Impl::RulesCounter): Don't use
atomic counter if lock-free aliases aren't available.
* testsuite/29_atomics/atomic/lock_free_aliases.cc: XFAIL for
targets without lock-free word-size compare_exchange.
---
 libstdc++-v3/include/bits/version.def  | 1 +
 libstdc++-v3/include/bits/version.h| 2 +-
 libstdc++-v3/include/std/atomic| 6 +++---
 libstdc++-v3/src/c++20/tzdb.cc | 7 ++-
 .../testsuite/29_atomics/atomic/lock_free_aliases.cc   | 1 +
 5 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/libstdc++-v3/include/bits/version.def 
b/libstdc++-v3/include/bits/version.def
index 502961eb269..d298420121b 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -739,6 +739,7 @@ ftms = {
   values = {
 v = 201907;
 cxxmin = 20;
+extra_cond = "(__GCC_ATOMIC_INT_LOCK_FREE | __GCC_ATOMIC_LONG_LOCK_FREE | 
__GCC_ATOMIC_CHAR_LOCK_FREE) & 2";
   };
 };
 
diff --git a/libstdc++-v3/include/bits/version.h 
b/libstdc++-v3/include/bits/version.h
index 7a6fbd35e2e..9107b45a484 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -819,7 +819,7 @@
 #undef __glibcxx_want_atomic_float
 
 #if !defined(__cpp_lib_atomic_lock_free_type_aliases)
-# if (__cplusplus >= 202002L)
+# if (__cplusplus >= 202002L) && ((__GCC_ATOMIC_INT_LOCK_FREE | 
__GCC_ATOMIC_LONG_LOCK_FREE | __GCC_ATOMIC_CHAR_LOCK_FREE) & 2)
 #  define __glibcxx_atomic_lock_free_type_aliases 201907L
 #  if defined(__glibcxx_want_all) || 
defined(__glibcxx_want_atomic_lock_free_type_aliases)
 #   define __cpp_lib_atomic_lock_free_type_aliases 201907L
diff --git a/libstdc++-v3/include/std/atomic b/libstdc++-v3/include/std/atomic
index 559f8370459..1462cf5ec23 100644
--- a/libstdc++-v3/include/std/atomic
+++ b/libstdc++-v3/include/std/atomic
@@ -1774,13 +1774,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 = atomic>;
   using atomic_unsigned_lock_free
 = atomic>;
-# elif ATOMIC_INT_LOCK_FREE || !(ATOMIC_LONG_LOCK_FREE || 
ATOMIC_CHAR_LOCK_FREE)
+# elif ATOMIC_INT_LOCK_FREE == 2
   using atomic_signed_lock_free = atomic;
   using atomic_unsigned_lock_free = atomic;
-# elif ATOMIC_LONG_LOCK_FREE
+# elif ATOMIC_LONG_LOCK_FREE == 2
   using atomic_signed_lock_free = atomic;
   using atomic_unsigned_lock_free = atomic;
-# elif ATOMIC_CHAR_LOCK_FREE
+# elif ATOMIC_CHAR_LOCK_FREE == 2
   using atomic_signed_lock_free = atomic;
   using atomic_unsigned_lock_free = atomic;
 # else
diff --git a/libstdc++-v3/src/c++20/tzdb.cc b/libstdc++-v3/src/c++20/tzdb.cc
index e03f4a5c32a..890a4c53e2d 100644
--- a/libstdc++-v3/src/c++20/tzdb.cc
+++ b/libstdc++-v3/src/c++20/tzdb.cc
@@ -651,7 +651,7 @@ namespace std::chrono
 template requires _Tp::is_always_lock_free
   struct RulesCounter<_Tp>
   {
-   atomic_signed_lock_free counter{0};
+   _Tp counter{0};
 
void
increment()
@@ -703,7 +703,12 @@ namespace std::chrono
   };
 #endif // __GTHREADS && __cpp_lib_atomic_wait
 
+#if __cpp_lib_atomic_lock_free_type_aliases
 RulesCounter rules_counter;
+#else
+RulesCounter rules_counter;
+#endif
+
 #else // TZDB_DISABLED
 _Impl(weak_ptr) { }
 struct {
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic/lock_free_aliases.cc 
b/libstdc++-v3/testsuite/29_atomics/atomic/lock_free_aliases.cc
index 372a63129ff..489d181d136 100644
--- a/libstdc++-v3/testsuite/29_atomics/atomic/lock_free_aliases.cc
+++ b/libstdc++-v3/testsuite/29_atomics/atomic/lock_free_aliases.cc
@@ -1,5 +1,6 @@
 // { dg-do compile { target c++20 } }
 // { dg-add-options no_pch }
+// { dg-require-atomic-cmpxchg-word "PR libstdc++/114103" }
 
 #include 
 
-- 
2.43.2



Re: [PATCH] libstdc++: Better diagnostics for std::format errors

2024-03-07 Thread Jonathan Wakely
Pushed to trunk.

On Fri, 1 Mar 2024 at 15:09, Jonathan Wakely  wrote:

> Does the text of these new diagnostics look good?
>
> There are of course other ways for a type to be not-formattable (e.g.
> the formatter::format member doesn't return the right type or has some
> other kind of incorrect signature, or the formatter::parse member isn't
> constexpr) but we can't predict/detect them all reliably. This just
> attempts to give a user-friendly explanation for a couple of common
> mistakes. It should not have any false positives, because the
> basic_format_arg constructor requires __formattable_with<_Tp, _Context>
> so if either of these assertions fails, constructing __arg will fail
> too.  The static_assert only adds a more readable error for a
> compilation that's going to fail anyway.
>
> Tested x86_64-linux.
>
> -- >8 --
>
> This adds two new static_assert messages to the internals of
> std::make_format_args to give better diagnostics for invalid format
> args. Rather than just getting an error saying that basic_format_arg
> cannot be constructed, we get more specific errors for the cases where
> std::formatter isn't specialized for the type at all, and where it's
> specialized but only meets the BasicFormatter requirements and so can
> only format non-const arguments.
>
> Also add a test for the existing static_assert when constructing a
> format_string for non-formattable args.
>
> libstdc++-v3/ChangeLog:
>
> * include/std/format (_Arg_store::_S_make_elt): Add two
> static_assert checks to give more user-friendly error messages.
> * testsuite/lib/prune.exp (libstdc++-dg-prune): Prune another
> form of "in requirements with" note.
> * testsuite/std/format/arguments/args_neg.cc: Check for
> user-friendly diagnostics for non-formattable types.
> * testsuite/std/format/string_neg.cc: Likewise.
> ---
>  libstdc++-v3/include/std/format   | 13 +++
>  libstdc++-v3/testsuite/lib/prune.exp  |  1 +
>  .../std/format/arguments/args_neg.cc  | 34 ++-
>  .../testsuite/std/format/string_neg.cc|  4 +++
>  4 files changed, 51 insertions(+), 1 deletion(-)
>
> diff --git a/libstdc++-v3/include/std/format
> b/libstdc++-v3/include/std/format
> index ee189f9086c..1e839e88db4 100644
> --- a/libstdc++-v3/include/std/format
> +++ b/libstdc++-v3/include/std/format
> @@ -3704,6 +3704,19 @@ namespace __format
> static _Element_t
> _S_make_elt(_Tp& __v)
> {
> + using _Tq = remove_const_t<_Tp>;
> + using _CharT = typename _Context::char_type;
> + static_assert(is_default_constructible_v>,
> +   "std::formatter must be specialized for the type "
> +   "of each format arg");
> + using __format::__formattable_with;
> + if constexpr (is_const_v<_Tp>)
> +   if constexpr (!__formattable_with<_Tp, _Context>)
> + if constexpr (__formattable_with<_Tq, _Context>)
> +   static_assert(__formattable_with<_Tp, _Context>,
> + "format arg must be non-const because its "
> + "std::formatter specialization has a "
> + "non-const reference parameter");
>   basic_format_arg<_Context> __arg(__v);
>   if constexpr (_S_values_only)
> return __arg._M_val;
> diff --git a/libstdc++-v3/testsuite/lib/prune.exp
> b/libstdc++-v3/testsuite/lib/prune.exp
> index 24a15ccad22..071dcf34c1e 100644
> --- a/libstdc++-v3/testsuite/lib/prune.exp
> +++ b/libstdc++-v3/testsuite/lib/prune.exp
> @@ -54,6 +54,7 @@ proc libstdc++-dg-prune { system text } {
>  regsub -all "(^|\n)\[^\n\]*:   . skipping \[0-9\]* instantiation
> contexts \[^\n\]*" $text "" text
>  regsub -all "(^|\n)\[^\n\]*:   in .constexpr. expansion \[^\n\]*"
> $text "" text
>  regsub -all "(^|\n)\[^\n\]*:   in requirements  .with\[^\n\]*" $text
> "" text
> +regsub -all "(^|\n)\[^\n\]*:   in requirements with\[^\n\]*" $text ""
> text
>  regsub -all "(^|\n)inlined from \[^\n\]*" $text "" text
>  # Why doesn't GCC need these to strip header context?
>  regsub -all "(^|\n)In file included from \[^\n\]*" $text "" text
> diff --git a/libstdc++-v3/testsuite/std/format/arguments/args_neg.cc
> b/libstdc++-v3/testsuite/std/format/arguments/args_neg.cc
> index 16ac3040146..ded56fe63ab 100644
> --- a/libstdc++-v3/testsuite/std/fo

[committed] libstdc++: Update expiry times for leap seconds lists

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

-- >8 --

The list in tzdb.cc isn't the only hardcoded list of leap seconds in the
library, there's the one defined inline in  (to avoid loading
the tzdb for the common case) and another in a testcase. This updates
them to note that there are no new leap seconds in 2024 either, until at
least 2024-12-28.

libstdc++-v3/ChangeLog:

* include/std/chrono (__get_leap_second_info): Update expiry
time for hardcoded list of leap seconds.
* testsuite/std/time/tzdb/leap_seconds.cc: Update comment.
---
 libstdc++-v3/include/std/chrono  | 2 +-
 libstdc++-v3/testsuite/std/time/tzdb/leap_seconds.cc | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono
index a59af34567c..3a9751781d2 100644
--- a/libstdc++-v3/include/std/chrono
+++ b/libstdc++-v3/include/std/chrono
@@ -3243,7 +3243,7 @@ namespace __detail
   };
   // The list above is known to be valid until (at least) this date
   // and only contains positive leap seconds.
-  const sys_seconds __expires(1703721600s); // 2023-12-28 00:00:00 UTC
+  const sys_seconds __expires(1735344000s); // 2024-12-28 00:00:00 UTC
 
 #if _GLIBCXX_USE_CXX11_ABI || ! _GLIBCXX_USE_DUAL_ABI
   if (__ss > __expires)
diff --git a/libstdc++-v3/testsuite/std/time/tzdb/leap_seconds.cc 
b/libstdc++-v3/testsuite/std/time/tzdb/leap_seconds.cc
index f5401a24526..5999635a89f 100644
--- a/libstdc++-v3/testsuite/std/time/tzdb/leap_seconds.cc
+++ b/libstdc++-v3/testsuite/std/time/tzdb/leap_seconds.cc
@@ -21,7 +21,7 @@ void
 test_load_leapseconds()
 {
   std::ofstream("leapseconds") << R"(
-# These are all the real leap seconds as of 2022:
+# These are all the real leap seconds as of 2024:
 Leap   1972Jun 30  23:59:60+   S
 Leap   1972Dec 31  23:59:60+   S
 Leap   1973Dec 31  23:59:60+   S
-- 
2.43.2



[committed] libstdc++: Replace unnecessary uses of built-ins in testsuite

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

-- >8 --

I don't see why we should rely on __builtin_memset etc. in tests. We can
just include  and use the public API.

libstdc++-v3/ChangeLog:

* testsuite/23_containers/deque/allocator/default_init.cc: Use
std::memset instead of __builtin_memset.
* testsuite/23_containers/forward_list/allocator/default_init.cc:
Likewise.
* testsuite/23_containers/list/allocator/default_init.cc:
Likewise.
* testsuite/23_containers/map/allocator/default_init.cc:
Likewise.
* testsuite/23_containers/set/allocator/default_init.cc:
Likewise.
* testsuite/23_containers/unordered_map/allocator/default_init.cc:
Likewise.
* testsuite/23_containers/unordered_set/allocator/default_init.cc:
Likewise.
* testsuite/23_containers/vector/allocator/default_init.cc:
Likewise.
* testsuite/23_containers/vector/bool/allocator/default_init.cc:
Likewise.
* testsuite/29_atomics/atomic/compare_exchange_padding.cc:
Likewise.
* testsuite/util/atomic/wait_notify_util.h: Likewise.
---
 .../23_containers/deque/allocator/default_init.cc |  5 +++--
 .../forward_list/allocator/default_init.cc|  5 +++--
 .../23_containers/list/allocator/default_init.cc  |  5 +++--
 .../23_containers/map/allocator/default_init.cc   |  5 +++--
 .../23_containers/set/allocator/default_init.cc   |  5 +++--
 .../unordered_map/allocator/default_init.cc   |  5 +++--
 .../unordered_set/allocator/default_init.cc   |  5 +++--
 .../23_containers/vector/allocator/default_init.cc|  5 +++--
 .../vector/bool/allocator/default_init.cc |  5 +++--
 .../29_atomics/atomic/compare_exchange_padding.cc |  5 +++--
 libstdc++-v3/testsuite/util/atomic/wait_notify_util.h | 11 +--
 11 files changed, 35 insertions(+), 26 deletions(-)

diff --git 
a/libstdc++-v3/testsuite/23_containers/deque/allocator/default_init.cc 
b/libstdc++-v3/testsuite/23_containers/deque/allocator/default_init.cc
index ce8c6ba8114..63ada98d048 100644
--- a/libstdc++-v3/testsuite/23_containers/deque/allocator/default_init.cc
+++ b/libstdc++-v3/testsuite/23_containers/deque/allocator/default_init.cc
@@ -22,6 +22,7 @@
 #include 
 #include 
 
+#include 
 #include 
 
 using T = int;
@@ -34,7 +35,7 @@ void test01()
   typedef std::deque test_type;
 
   __gnu_cxx::__aligned_buffer buf;
-  __builtin_memset(buf._M_addr(), ~0, sizeof(test_type));
+  std::memset(buf._M_addr(), ~0, sizeof(test_type));
 
   test_type *tmp = ::new(buf._M_addr()) test_type;
 
@@ -49,7 +50,7 @@ void test02()
   typedef std::deque test_type;
 
   __gnu_cxx::__aligned_buffer buf;
-  __builtin_memset(buf._M_addr(), ~0, sizeof(test_type));
+  std::memset(buf._M_addr(), ~0, sizeof(test_type));
 
   test_type *tmp = ::new(buf._M_addr()) test_type();
 
diff --git 
a/libstdc++-v3/testsuite/23_containers/forward_list/allocator/default_init.cc 
b/libstdc++-v3/testsuite/23_containers/forward_list/allocator/default_init.cc
index 1865e39a885..d8a8bdf05a9 100644
--- 
a/libstdc++-v3/testsuite/23_containers/forward_list/allocator/default_init.cc
+++ 
b/libstdc++-v3/testsuite/23_containers/forward_list/allocator/default_init.cc
@@ -22,6 +22,7 @@
 #include 
 #include 
 
+#include 
 #include 
 
 using T = int;
@@ -34,7 +35,7 @@ void test01()
   typedef std::forward_list test_type;
 
   __gnu_cxx::__aligned_buffer buf;
-  __builtin_memset(buf._M_addr(), ~0, sizeof(test_type));
+  std::memset(buf._M_addr(), ~0, sizeof(test_type));
 
   test_type *tmp = ::new(buf._M_addr()) test_type;
 
@@ -49,7 +50,7 @@ void test02()
   typedef std::forward_list test_type;
 
   __gnu_cxx::__aligned_buffer buf;
-  __builtin_memset(buf._M_addr(), ~0, sizeof(test_type));
+  std::memset(buf._M_addr(), ~0, sizeof(test_type));
 
   test_type *tmp = ::new(buf._M_addr()) test_type();
 
diff --git 
a/libstdc++-v3/testsuite/23_containers/list/allocator/default_init.cc 
b/libstdc++-v3/testsuite/23_containers/list/allocator/default_init.cc
index ab19ca7070c..cffad227bc0 100644
--- a/libstdc++-v3/testsuite/23_containers/list/allocator/default_init.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/allocator/default_init.cc
@@ -22,6 +22,7 @@
 #include 
 #include 
 
+#include 
 #include 
 
 using T = int;
@@ -34,7 +35,7 @@ void test01()
   typedef std::list test_type;
 
   __gnu_cxx::__aligned_buffer buf;
-  __builtin_memset(buf._M_addr(), ~0, sizeof(test_type));
+  std::memset(buf._M_addr(), ~0, sizeof(test_type));
 
   VERIFY( buf._M_ptr()->get_allocator().state != 0 );
 
@@ -51,7 +52,7 @@ void test02()
   typedef std::list test_type;
 
   __gnu_cxx::__aligned_buffer buf;
-  __builtin_memset(buf._M_addr(), ~0, sizeof(test_type));
+  std::memset(buf._M_addr(), ~0, sizeof(test_type));
 
   VERIFY( buf._M_ptr()->get_allocator().state != 0 );
 
diff --git a/libstdc++-v3/testsuite/23_containers/map/allocator/default_init.cc 

[PATCH] libstdc++: Document that _GLIBCXX_CONCEPT_CHECKS might be removed in future

2024-03-07 Thread Jonathan Wakely
Any objection to this update to make the docs reflect reality?

-- >8 --

The macro-based concept checks are unmaintained and do not support C++11
or later, so reject valid code. If nobody plans to update them we should
consider removing them. Alternatively, we could ignore the macro for
C++11 and later, so they have no effect and don't reject valid code.

libstdc++-v3/ChangeLog:

* doc/xml/manual/debug.xml: Document that concept checking might
be removed in future.
* doc/xml/manual/extensions.xml: Likewise.
---
 libstdc++-v3/doc/xml/manual/debug.xml  |  2 ++
 libstdc++-v3/doc/xml/manual/extensions.xml | 18 --
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/libstdc++-v3/doc/xml/manual/debug.xml 
b/libstdc++-v3/doc/xml/manual/debug.xml
index 42d4d32aa29..7f6d0876fc6 100644
--- a/libstdc++-v3/doc/xml/manual/debug.xml
+++ b/libstdc++-v3/doc/xml/manual/debug.xml
@@ -351,6 +351,8 @@
 
The Compile-Time
   Checks extension has compile-time checks for many algorithms.
+  These checks were designed for C++98 and have not been updated to work
+  with C++11 and later standards. They might be removed at a future date.
   
 
 
diff --git a/libstdc++-v3/doc/xml/manual/extensions.xml 
b/libstdc++-v3/doc/xml/manual/extensions.xml
index d4fe2f509d4..490a50cc331 100644
--- a/libstdc++-v3/doc/xml/manual/extensions.xml
+++ b/libstdc++-v3/doc/xml/manual/extensions.xml
@@ -77,8 +77,7 @@ extensions, be aware of two things:
   object file.  The checks are also cleaner and easier to read and
   understand.

-   They are off by default for all versions of GCC from 3.0 to 3.4 (the
-  latest release at the time of writing).
+   They are off by default for all GCC 3.0 and all later versions.
   They can be enabled at configure time with
   --enable-concept-checks.
   You can enable them on a per-translation-unit basis with
@@ -89,10 +88,17 @@ extensions, be aware of two things:

 
Please note that the concept checks only validate the requirements
-   of the old C++03 standard. C++11 was expected to have first-class
-   support for template parameter constraints based on concepts in the core
-   language. This would have obviated the need for the library-simulated 
concept
-   checking described above, but was not part of C++11.
+   of the old C++03 standard and reject some valid code that meets the relaxed
+   requirements of C++11 and later standards.
+   C++11 was expected to have first-class support for template parameter
+   constraints based on concepts in the core language.
+   This would have obviated the need for the library-simulated concept checking
+   described above, but was not part of C++11.
+   C++20 adds a different model of concepts, which is now used to constrain
+   some new parts of the C++20 library, e.g. the
+   ranges header and the new overloads in the
+   algorithm header for working with ranges.
+   The old library-simulated concept checks might be removed at a future date.

 
 
-- 
2.43.2



Re: [PATCH] doc: Fix docs for -dD regarding predefined macros

2024-03-05 Thread Jonathan Wakely
On Tue, 5 Mar 2024 at 18:31, Joseph Myers wrote:
>
> On Tue, 5 Mar 2024, Jakub Jelinek wrote:
>
> > I can't bisect that far, supposedly predefined macros weren't included back
> > in 1996 when this was written but maybe it changed in 1999 or even earlier.
>
> It looks like this changed in 3.0 (so probably with the move to cpplib to
> provide the default preprocessor implementation), but I don't know why.


Ah, thanks for narrowing it down.

I'll push the doc change tomorrow.



[PATCH] doc: Fix docs for -dD regarding predefined macros

2024-03-05 Thread Jonathan Wakely
OK for trunk?

Or am I missing something and the docs are right? (sometimes? always?)


-- >8 --

The manual has always claimed that -dD differs from -dM by not
outputting predefined macros, but that's untrue. It has been untrue
since at least GCC 3.2 and probably even older.

gcc/ChangeLog:

* doc/cppopts.texi: Remove incorrect claim about -dD not
outputting predefined macros.
---
 gcc/doc/cppopts.texi | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/gcc/doc/cppopts.texi b/gcc/doc/cppopts.texi
index fa8f3d88c89..5b5b0848ae8 100644
--- a/gcc/doc/cppopts.texi
+++ b/gcc/doc/cppopts.texi
@@ -524,8 +524,7 @@ interpreted as a synonym for @option{-fdump-rtl-mach}.
 
 @opindex dD
 @item -dD
-Like @option{-dM} except in two respects: it does @emph{not} include the
-predefined macros, and it outputs @emph{both} the @samp{#define}
+Like @option{-dM} except that it outputs @emph{both} the @samp{#define}
 directives and the result of preprocessing.  Both kinds of output go to
 the standard output file.
 
-- 
2.43.2



Re: [PATCH v5] c++: implement [[gnu::non_owning]] [PR110358]

2024-03-04 Thread Jonathan Wakely

On 01/03/24 15:38 -0500, Jason Merrill wrote:

On 3/1/24 14:24, Marek Polacek wrote:

+@smallexample
+template 
+[[gnu::no_dangling(std::is_reference_v)]] int foo (T& t) @{


I think this function should return a reference.


The condition in the attribute can only ever be true if you call this
function with an explicit template argument list: foo(i). Is
that intentional?

And if T is non-const it can't be called with a temporary and so
dangling seems less of a problem for this function anyway, right?

Would it make more sense as something like this?

template 
[[gnu::no_dangling(std::is_lvalue_reference_v)]]
decltype(auto) foo(T&& t) {
  ...
}

Or is this getting too complex/subtle for a simple example?




[PATCH] gcc_update: Add missing generated files

2024-03-01 Thread Jonathan Wakely
Is this OK for trunk?

-- >8 --

I'm seeing errors for --enable-maintainer-mode builds due to incorrectly
regenerating these files. They should be touched by gcc_update so they
aren't regenerated unnecessarily.

contrib/ChangeLog:

* gcc_update: Add more generated files in libcc1, lto-plugin,
fixincludes, and libstdc++-v3.
---
 contrib/gcc_update | 8 
 1 file changed, 8 insertions(+)

diff --git a/contrib/gcc_update b/contrib/gcc_update
index 774c926e723..fac86d0e33e 100755
--- a/contrib/gcc_update
+++ b/contrib/gcc_update
@@ -70,6 +70,7 @@ files_and_dependencies () {
 # fixincludes
 fixincludes/configure: fixincludes/configure.ac fixincludes/aclocal.m4
 fixincludes/config.h.in: fixincludes/configure.ac fixincludes/aclocal.m4
+fixincludes/fixincl.x: fixincludes/inclhack.def fixincludes/fixincl.tpl
 # intl library
 intl/plural.c: intl/plural.y
 intl/plural-config.h: intl/plural.y
@@ -106,6 +107,7 @@ gcc/testsuite/gcc.dg/cpp/_Pragma3.c: 
gcc/testsuite/gcc.dg/cpp/mi1c.h
 # direct2s.c:35: warning: current file is older than direct2.c
 gcc/testsuite/gcc.dg/cpp/direct2s.c: gcc/testsuite/gcc.dg/cpp/direct2.c
 # lto-plugin
+lto-plugin/aclocal.m4: lto-plugin/configure.ac
 lto-plugin/configure: lto-plugin/configure.ac lto-plugin/aclocal.m4
 lto-plugin/Makefile.in: lto-plugin/Makefile.am lto-plugin/aclocal.m4
 # tools
@@ -186,7 +188,13 @@ libphobos/config.h.in: libphobos/configure.ac 
libphobos/aclocal.m4
 libphobos/configure: libphobos/configure.ac libphobos/aclocal.m4
 libphobos/src/Makefile.in: libphobos/src/Makefile.am libphobos/aclocal.m4
 libphobos/testsuite/Makefile.in: libphobos/testsuite/Makefile.am 
libphobos/aclocal.m4
+libstdc++-v3/aclocal.m4: libstdc++-v3/configure.ac libstdc++-v3/acinclude.m4
+libstdc++-v3/Makefile.in: libstdc++-v3/Makefile.am libstdc++-v3/aclocal.m4
+libstdc++-v3/configure: libstdc++-v3/configure.ac libstdc++-v3/acinclude.m4
 libstdc++-v3/include/bits/version.h: libstdc++-v3/include/bits/version.def 
libstdc++-v3/include/bits/version.tpl
+libcc1/aclocal.m4: libcc1/configure.ac
+libcc1/Makefile.in: libcc1/Makefile.am libcc1/configure.ac libcc1/aclocal.m4
+libcc1/configure: libcc1/configure.ac
 # Top level
 Makefile.in: Makefile.tpl Makefile.def
 configure: configure.ac config/acx.m4
-- 
2.43.2



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

2024-03-01 Thread Jonathan Wakely
This fixes a regression on all active branches.

Tested aarch64-linux.  

-- >8 --

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.
---
 libstdc++-v3/include/std/tuple| 14 ++
 .../testsuite/20_util/tuple/cons/114147.cc| 15 +++
 2 files changed, 29 insertions(+)
 create mode 100644 libstdc++-v3/testsuite/20_util/tuple/cons/114147.cc

diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index 9c89c13ab84..3065058e184 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -1550,6 +1550,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
@@ -2198,6 +2205,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);
-- 
2.43.2



[PATCH] libstdc++: Better diagnostics for std::format errors

2024-03-01 Thread Jonathan Wakely
Does the text of these new diagnostics look good?

There are of course other ways for a type to be not-formattable (e.g.
the formatter::format member doesn't return the right type or has some
other kind of incorrect signature, or the formatter::parse member isn't
constexpr) but we can't predict/detect them all reliably. This just
attempts to give a user-friendly explanation for a couple of common
mistakes. It should not have any false positives, because the
basic_format_arg constructor requires __formattable_with<_Tp, _Context>
so if either of these assertions fails, constructing __arg will fail
too.  The static_assert only adds a more readable error for a
compilation that's going to fail anyway.

Tested x86_64-linux.

-- >8 --

This adds two new static_assert messages to the internals of
std::make_format_args to give better diagnostics for invalid format
args. Rather than just getting an error saying that basic_format_arg
cannot be constructed, we get more specific errors for the cases where
std::formatter isn't specialized for the type at all, and where it's
specialized but only meets the BasicFormatter requirements and so can
only format non-const arguments.

Also add a test for the existing static_assert when constructing a
format_string for non-formattable args.

libstdc++-v3/ChangeLog:

* include/std/format (_Arg_store::_S_make_elt): Add two
static_assert checks to give more user-friendly error messages.
* testsuite/lib/prune.exp (libstdc++-dg-prune): Prune another
form of "in requirements with" note.
* testsuite/std/format/arguments/args_neg.cc: Check for
user-friendly diagnostics for non-formattable types.
* testsuite/std/format/string_neg.cc: Likewise.
---
 libstdc++-v3/include/std/format   | 13 +++
 libstdc++-v3/testsuite/lib/prune.exp  |  1 +
 .../std/format/arguments/args_neg.cc  | 34 ++-
 .../testsuite/std/format/string_neg.cc|  4 +++
 4 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index ee189f9086c..1e839e88db4 100644
--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -3704,6 +3704,19 @@ namespace __format
static _Element_t
_S_make_elt(_Tp& __v)
{
+ using _Tq = remove_const_t<_Tp>;
+ using _CharT = typename _Context::char_type;
+ static_assert(is_default_constructible_v>,
+   "std::formatter must be specialized for the type "
+   "of each format arg");
+ using __format::__formattable_with;
+ if constexpr (is_const_v<_Tp>)
+   if constexpr (!__formattable_with<_Tp, _Context>)
+ if constexpr (__formattable_with<_Tq, _Context>)
+   static_assert(__formattable_with<_Tp, _Context>,
+ "format arg must be non-const because its "
+ "std::formatter specialization has a "
+ "non-const reference parameter");
  basic_format_arg<_Context> __arg(__v);
  if constexpr (_S_values_only)
return __arg._M_val;
diff --git a/libstdc++-v3/testsuite/lib/prune.exp 
b/libstdc++-v3/testsuite/lib/prune.exp
index 24a15ccad22..071dcf34c1e 100644
--- a/libstdc++-v3/testsuite/lib/prune.exp
+++ b/libstdc++-v3/testsuite/lib/prune.exp
@@ -54,6 +54,7 @@ proc libstdc++-dg-prune { system text } {
 regsub -all "(^|\n)\[^\n\]*:   . skipping \[0-9\]* instantiation contexts 
\[^\n\]*" $text "" text
 regsub -all "(^|\n)\[^\n\]*:   in .constexpr. expansion \[^\n\]*" $text "" 
text
 regsub -all "(^|\n)\[^\n\]*:   in requirements  .with\[^\n\]*" $text "" 
text
+regsub -all "(^|\n)\[^\n\]*:   in requirements with\[^\n\]*" $text "" text
 regsub -all "(^|\n)inlined from \[^\n\]*" $text "" text
 # Why doesn't GCC need these to strip header context?
 regsub -all "(^|\n)In file included from \[^\n\]*" $text "" text
diff --git a/libstdc++-v3/testsuite/std/format/arguments/args_neg.cc 
b/libstdc++-v3/testsuite/std/format/arguments/args_neg.cc
index 16ac3040146..ded56fe63ab 100644
--- a/libstdc++-v3/testsuite/std/format/arguments/args_neg.cc
+++ b/libstdc++-v3/testsuite/std/format/arguments/args_neg.cc
@@ -6,7 +6,39 @@
 
 std::string rval() { return "path/etic/experience"; }
 
-void f()
+void test_rval()
 {
   (void)std::make_format_args(rval()); // { dg-error "cannot bind non-const 
lvalue reference" }
 }
+
+void test_missing_specialization()
+{
+  struct X { };
+  X x;
+  (void)std::make_format_args(x); // { dg-error "here" }
+// { dg-error "std::formatter must be specialized" "" { target *-*-* } 0 }
+}
+
+struct Y { };
+template<> class std::formatter {
+public:
+  constexpr typename format_parse_context::iterator
+  parse(format_parse_context& c)
+  { return c.begin(); }
+
+  template
+  typename C::iterator format(Y&, C&) const;
+};
+
+void 

[PATCH] libstdc++: Use [] for empty argument to automake macro

2024-03-01 Thread Jonathan Wakely
Does this look reasonable to push? There are lots of other uses of
AM_ENABLE_MULTILIB(, ..) in the tree, but I'll leave others to "fix"
those if needed.

-- >8 --

This seems to be needed to build with --enable-maintainer-mode but I
don't understand why it doesn't fail in the normal build.

libstdc++-v3/ChangeLog:

* configure.ac: Use [] for empty argument to AM_ENABLE_MULTILIB
macro.
---
 libstdc++-v3/configure.ac | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac
index 37396bd6ebb..1d6a94a16f2 100644
--- a/libstdc++-v3/configure.ac
+++ b/libstdc++-v3/configure.ac
@@ -11,7 +11,7 @@ AC_CONFIG_HEADER(config.h)
 ### am handles this now?  ORIGINAL_LD_FOR_MULTILIBS=$LD
 
 # Find the rest of the source tree framework.
-AM_ENABLE_MULTILIB(, ..)
+AM_ENABLE_MULTILIB([], ..)
 
 # Gets build, host, target, *_vendor, *_cpu, *_os, etc.
 #
-- 
2.43.2



[committed] libstdc++: Fix std::basic_format_arg::handle for BasicFormatters

2024-02-29 Thread Jonathan Wakely
Tested x86_64-linux. Pushed to trunk.

-- >8 --

std::basic_format_arg::handle is supposed to format its value as const
if that is valid, to reduce the number of instantiations of the
formatter's format function. I made a silly typo so that it checks
formattable_with not formattable_with,
which breaks support for BasicFormatters i.e. ones that can only format
non-const types.

There's a static_assert in the handle constructor which is supposed to
improve diagnostics for trying to format a const argument with a
formatter that doesn't support it. That condition can't fail, because
the std::basic_format_arg constructor is already constrained to check
that the argument type is formattable. The static_assert can be removed.

libstdc++-v3/ChangeLog:

* include/std/format (basic_format_arg::handle::__maybe_const_t):
Fix condition to check if const type is formattable.
(basic_format_arg::handle::handle(T&)): Remove redundant
static_assert.
* testsuite/std/format/formatter/basic.cc: New test.
---
 libstdc++-v3/include/std/format   |  6 +
 .../testsuite/std/format/formatter/basic.cc   | 24 +++
 2 files changed, 25 insertions(+), 5 deletions(-)
 create mode 100644 libstdc++-v3/testsuite/std/format/formatter/basic.cc

diff --git a/libstdc++-v3/include/std/format b/libstdc++-v3/include/std/format
index 961441e355b..ee189f9086c 100644
--- a/libstdc++-v3/include/std/format
+++ b/libstdc++-v3/include/std/format
@@ -3210,7 +3210,7 @@ namespace __format
// Format as const if possible, to reduce instantiations.
template
  using __maybe_const_t
-   = __conditional_t<__formattable<_Tp>, const _Tp, _Tp>;
+   = __conditional_t<__formattable, const _Tp, _Tp>;
 
template
  static void
@@ -3228,10 +3228,6 @@ namespace __format
  explicit
  handle(_Tp& __val) noexcept
  {
-   if constexpr (!__formattable)
- static_assert(!is_const_v<_Tp>, "std::format argument must be "
- "non-const for this type");
-
this->_M_ptr = __builtin_addressof(__val);
auto __func = _S_format<__maybe_const_t<_Tp>>;
this->_M_func = reinterpret_cast(__func);
diff --git a/libstdc++-v3/testsuite/std/format/formatter/basic.cc 
b/libstdc++-v3/testsuite/std/format/formatter/basic.cc
new file mode 100644
index 000..56c18864135
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/format/formatter/basic.cc
@@ -0,0 +1,24 @@
+// { dg-do compile { target c++20 } }
+
+// BasicFormatter requirements do not require a const parameter.
+
+#include 
+
+struct X { };
+
+template<> struct std::formatter
+{
+  constexpr auto parse(format_parse_context& ctx)
+  { return ctx.begin(); }
+
+  // Takes non-const X&
+  format_context::iterator format(X&, format_context& ctx) const
+  {
+auto out = ctx.out();
+*out++ = 'x';
+return out;
+  }
+};
+
+X x;
+auto s = std::format("{}", x);
-- 
2.43.2



[committed] libstdc++: Fix conditions for using memcmp in std::lexicographical_compare_three_way [PR113960]

2024-02-29 Thread Jonathan Wakely
Tested aarch64-linux, powerpc-linux (power 7 BE), x86_64-linux.
The bug reporter tested it on s390x too.

Pushed to trunk. This should be backported too.

-- >8 --

The change in r11-2981-g2f983fa69005b6 meant that
std::lexicographical_compare_three_way started to use memcmp for
unsigned integers on big endian targets, but for that to be valid we
need the two value types to have the same size and we need to use that
size to compute the length passed to memcmp.

I already defined a __is_memcmp_ordered_with trait that does the right
checks, std::lexicographical_compare_three_way just needs to use it.

libstdc++-v3/ChangeLog:

PR libstdc++/113960
* include/bits/stl_algobase.h (__is_byte_iter): Replace with ...
(__memcmp_ordered_with): New concept.
(lexicographical_compare_three_way): Use __memcmp_ordered_with
instead of __is_byte_iter. Use correct length for memcmp.
* testsuite/25_algorithms/lexicographical_compare_three_way/113960.cc:
New test.
---
 libstdc++-v3/include/bits/stl_algobase.h  | 41 ++-
 .../113960.cc | 15 +++
 2 files changed, 37 insertions(+), 19 deletions(-)
 create mode 100644 
libstdc++-v3/testsuite/25_algorithms/lexicographical_compare_three_way/113960.cc

diff --git a/libstdc++-v3/include/bits/stl_algobase.h 
b/libstdc++-v3/include/bits/stl_algobase.h
index d534e02871f..74ff42d4f39 100644
--- a/libstdc++-v3/include/bits/stl_algobase.h
+++ b/libstdc++-v3/include/bits/stl_algobase.h
@@ -1806,11 +1806,14 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
 }
 
 #if __cpp_lib_three_way_comparison
-  // Iter points to a contiguous range of unsigned narrow character type
-  // or std::byte, suitable for comparison by memcmp.
-  template
-concept __is_byte_iter = contiguous_iterator<_Iter>
-  && __is_memcmp_ordered>::__value;
+  // Both iterators refer to contiguous ranges of unsigned narrow characters,
+  // or std::byte, or big-endian unsigned integers, suitable for comparison
+  // using memcmp.
+  template
+concept __memcmp_ordered_with
+  = (__is_memcmp_ordered_with,
+ iter_value_t<_Iter2>>::__value)
+ && contiguous_iterator<_Iter1> && contiguous_iterator<_Iter2>;
 
   // Return a struct with two members, initialized to the smaller of x and y
   // (or x if they compare equal) and the result of the comparison x <=> y.
@@ -1860,20 +1863,20 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
   if (!std::__is_constant_evaluated())
if constexpr (same_as<_Comp, __detail::_Synth3way>
  || same_as<_Comp, compare_three_way>)
- if constexpr (__is_byte_iter<_InputIter1>)
-   if constexpr (__is_byte_iter<_InputIter2>)
- {
-   const auto [__len, __lencmp] = _GLIBCXX_STD_A::
- __min_cmp(__last1 - __first1, __last2 - __first2);
-   if (__len)
- {
-   const auto __c
- = __builtin_memcmp(&*__first1, &*__first2, __len) <=> 0;
-   if (__c != 0)
- return __c;
- }
-   return __lencmp;
- }
+ if constexpr (__memcmp_ordered_with<_InputIter1, _InputIter2>)
+   {
+ const auto [__len, __lencmp] = _GLIBCXX_STD_A::
+   __min_cmp(__last1 - __first1, __last2 - __first2);
+ if (__len)
+   {
+ const auto __blen = __len * sizeof(*__first1);
+ const auto __c
+   = __builtin_memcmp(&*__first1, &*__first2, __blen) <=> 0;
+ if (__c != 0)
+   return __c;
+   }
+ return __lencmp;
+   }
 
   while (__first1 != __last1)
{
diff --git 
a/libstdc++-v3/testsuite/25_algorithms/lexicographical_compare_three_way/113960.cc
 
b/libstdc++-v3/testsuite/25_algorithms/lexicographical_compare_three_way/113960.cc
new file mode 100644
index 000..d51ae1a3d50
--- /dev/null
+++ 
b/libstdc++-v3/testsuite/25_algorithms/lexicographical_compare_three_way/113960.cc
@@ -0,0 +1,15 @@
+// { dg-do run { target c++20 } }
+
+// PR libstdc++/113960
+// std::map with std::vector as input overwrites itself with c++20, on s390x
+
+#include 
+#include 
+
+int main()
+{
+  unsigned short a1[] { 1, 2, 3 };
+  unsigned short a2[] { 1, 2, 4 };
+  // Incorrect memcmp comparison for big endian targets.
+  VERIFY( std::lexicographical_compare_three_way(a1, a1+3, a2, a2+3) < 0 );
+}
-- 
2.43.2



[PATCH v2] libstdc++: Add more nodiscard uses in

2024-02-29 Thread Jonathan Wakely
We need to add [[nodiscard]] to the comparison ops in 
too, which I missed in the v1 patch.

Tested aarch64-linux. Pushed to trunk (yesterday).
commit 26d6a714b29eeef77591f136f5162622a549d8fd
Author: Jonathan Wakely 
Date:   Mon Feb 26 13:09:02 2024

libstdc++: Add more nodiscard uses in 

Add [[nodiscard]] to vector::at and to comparison operators.

libstdc++-v3/ChangeLog:

* include/bits/stl_bvector.h (vector::at): Add
nodiscard.
* include/bits/stl_vector.h (vector::at): Likewise.
(operator==, operator<=>, operator<, operator!=, operator>)
(operator<=, operator>=): Likewise.
* include/debug/vector (operator==, operator<=>, operator<)
(operator!=, operator>, operator<=, operator>=): Likewise.
* testsuite/23_containers/vector/nodiscard.cc: New test.

diff --git a/libstdc++-v3/include/bits/stl_bvector.h 
b/libstdc++-v3/include/bits/stl_bvector.h
index aa5644b4a0e..2c8b892b07a 100644
--- a/libstdc++-v3/include/bits/stl_bvector.h
+++ b/libstdc++-v3/include/bits/stl_bvector.h
@@ -1101,7 +1101,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
   }
 
 public:
-  _GLIBCXX20_CONSTEXPR
+  _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
   reference
   at(size_type __n)
   {
@@ -1109,7 +1109,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
return (*this)[__n];
   }
 
-  _GLIBCXX20_CONSTEXPR
+  _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
   const_reference
   at(size_type __n) const
   {
diff --git a/libstdc++-v3/include/bits/stl_vector.h 
b/libstdc++-v3/include/bits/stl_vector.h
index 6a9543eefce..a8d387f40a1 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -1172,7 +1172,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*  is first checked that it is in the range of the vector.  The
*  function throws out_of_range if the check fails.
*/
-  _GLIBCXX20_CONSTEXPR
+  _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
   reference
   at(size_type __n)
   {
@@ -1191,7 +1191,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*  is first checked that it is in the range of the vector.  The
*  function throws out_of_range if the check fails.
*/
-  _GLIBCXX20_CONSTEXPR
+  _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
   const_reference
   at(size_type __n) const
   {
@@ -2042,7 +2042,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*  and if corresponding elements compare equal.
   */
   template
-_GLIBCXX20_CONSTEXPR
+_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
 inline bool
 operator==(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
 { return (__x.size() == __y.size()
@@ -2061,7 +2061,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*  `<` and `>=` etc.
   */
   template
-_GLIBCXX20_CONSTEXPR
+[[nodiscard]] _GLIBCXX20_CONSTEXPR
 inline __detail::__synth3way_t<_Tp>
 operator<=>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
 {
@@ -2082,32 +2082,32 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*  See std::lexicographical_compare() for how the determination is made.
   */
   template
-inline bool
+_GLIBCXX_NODISCARD inline bool
 operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
 { return std::lexicographical_compare(__x.begin(), __x.end(),
  __y.begin(), __y.end()); }
 
   /// Based on operator==
   template
-inline bool
+_GLIBCXX_NODISCARD inline bool
 operator!=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
 { return !(__x == __y); }
 
   /// Based on operator<
   template
-inline bool
+_GLIBCXX_NODISCARD inline bool
 operator>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
 { return __y < __x; }
 
   /// Based on operator<
   template
-inline bool
+_GLIBCXX_NODISCARD inline bool
 operator<=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
 { return !(__y < __x); }
 
   /// Based on operator<
   template
-inline bool
+_GLIBCXX_NODISCARD inline bool
 operator>=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
 { return !(__x < __y); }
 #endif // three-way comparison
diff --git a/libstdc++-v3/include/debug/vector 
b/libstdc++-v3/include/debug/vector
index 5a0fc808651..216822975a2 100644
--- a/libstdc++-v3/include/debug/vector
+++ b/libstdc++-v3/include/debug/vector
@@ -866,7 +866,7 @@ namespace __debug
 };
 
   template
-_GLIBCXX20_CONSTEXPR
+_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
 inline bool
 operator==(const vector<_Tp, _Alloc>& __lhs,
   const vector<_T

Re: [committed] libstdc++: Fix noexcept on dtors in [PR114152]

2024-02-28 Thread Jonathan Wakely
Oops, sorry, I CC'd the wrong Victor on this patch (you've both
reported libstdc++ bugs today and I grabbed the email address from the
wrong browser tab).

On Wed, 28 Feb 2024 at 14:53, Jonathan Wakely wrote:
>
> Tested x86_64-linux, pushed to trunk. Backport to gcc-13 to follow.
>
> -- >8 --
>
> The PR points out that the destructors all have incorrect
> noexcept-specifiers.
>
> libstdc++-v3/ChangeLog:
>
> PR libstdc++/114152
> * include/experimental/scope (scope_exit scope_fail): Make
> destructor unconditionally noexcept.
> (scope_sucess): Fix noexcept-specifier.
> * testsuite/experimental/scopeguard/114152.cc: New test.
> ---
>  libstdc++-v3/include/experimental/scope   |  6 ++---
>  .../experimental/scopeguard/114152.cc | 24 +++
>  2 files changed, 27 insertions(+), 3 deletions(-)
>  create mode 100644 libstdc++-v3/testsuite/experimental/scopeguard/114152.cc
>
> diff --git a/libstdc++-v3/include/experimental/scope 
> b/libstdc++-v3/include/experimental/scope
> index 5dbeac14795..ea273e8c095 100644
> --- a/libstdc++-v3/include/experimental/scope
> +++ b/libstdc++-v3/include/experimental/scope
> @@ -97,7 +97,7 @@ namespace experimental::inline fundamentals_v3
>scope_exit& operator=(const scope_exit&) = delete;
>scope_exit& operator=(scope_exit&&) = delete;
>
> -  ~scope_exit() noexcept(noexcept(this->_M_exit_function))
> +  ~scope_exit() noexcept
>{
> if (_M_execute_on_destruction)
>   _M_exit_function();
> @@ -157,7 +157,7 @@ namespace experimental::inline fundamentals_v3
>scope_fail& operator=(const scope_fail&) = delete;
>scope_fail& operator=(scope_fail&&) = delete;
>
> -  ~scope_fail() noexcept(noexcept(this->_M_exit_function))
> +  ~scope_fail() noexcept
>{
> if (std::uncaught_exceptions() > _M_uncaught_init)
>   _M_exit_function();
> @@ -211,7 +211,7 @@ namespace experimental::inline fundamentals_v3
>scope_success& operator=(const scope_success&) = delete;
>scope_success& operator=(scope_success&&) = delete;
>
> -  ~scope_success() noexcept(noexcept(this->_M_exit_function))
> +  ~scope_success() noexcept(noexcept(this->_M_exit_function()))
>{
> if (std::uncaught_exceptions() <= _M_uncaught_init)
>   _M_exit_function();
> diff --git a/libstdc++-v3/testsuite/experimental/scopeguard/114152.cc 
> b/libstdc++-v3/testsuite/experimental/scopeguard/114152.cc
> new file mode 100644
> index 000..63c1f710e9f
> --- /dev/null
> +++ b/libstdc++-v3/testsuite/experimental/scopeguard/114152.cc
> @@ -0,0 +1,24 @@
> +// { dg-do compile { target c++20 } }
> +
> +// PR libstdc++/114152
> +// Wrong exception specifiers for LFTSv3 scope guard destructors
> +
> +#include 
> +
> +using namespace std::experimental;
> +
> +struct F {
> +  void operator()() noexcept(false);
> +};
> +
> +static_assert( noexcept(std::declval&>().~scope_exit()) );
> +static_assert( noexcept(std::declval&>().~scope_fail()) );
> +static_assert( ! 
> noexcept(std::declval&>().~scope_success()) );
> +
> +struct G {
> +  void operator()() noexcept(true);
> +};
> +
> +static_assert( noexcept(std::declval&>().~scope_exit()) );
> +static_assert( noexcept(std::declval&>().~scope_fail()) );
> +static_assert( noexcept(std::declval&>().~scope_success()) 
> );
> --
> 2.43.0
>



[committed] libstdc++: Fix noexcept on dtors in [PR114152]

2024-02-28 Thread Jonathan Wakely
Tested x86_64-linux, pushed to trunk. Backport to gcc-13 to follow.

-- >8 --

The PR points out that the destructors all have incorrect
noexcept-specifiers.

libstdc++-v3/ChangeLog:

PR libstdc++/114152
* include/experimental/scope (scope_exit scope_fail): Make
destructor unconditionally noexcept.
(scope_sucess): Fix noexcept-specifier.
* testsuite/experimental/scopeguard/114152.cc: New test.
---
 libstdc++-v3/include/experimental/scope   |  6 ++---
 .../experimental/scopeguard/114152.cc | 24 +++
 2 files changed, 27 insertions(+), 3 deletions(-)
 create mode 100644 libstdc++-v3/testsuite/experimental/scopeguard/114152.cc

diff --git a/libstdc++-v3/include/experimental/scope 
b/libstdc++-v3/include/experimental/scope
index 5dbeac14795..ea273e8c095 100644
--- a/libstdc++-v3/include/experimental/scope
+++ b/libstdc++-v3/include/experimental/scope
@@ -97,7 +97,7 @@ namespace experimental::inline fundamentals_v3
   scope_exit& operator=(const scope_exit&) = delete;
   scope_exit& operator=(scope_exit&&) = delete;
 
-  ~scope_exit() noexcept(noexcept(this->_M_exit_function))
+  ~scope_exit() noexcept
   {
if (_M_execute_on_destruction)
  _M_exit_function();
@@ -157,7 +157,7 @@ namespace experimental::inline fundamentals_v3
   scope_fail& operator=(const scope_fail&) = delete;
   scope_fail& operator=(scope_fail&&) = delete;
 
-  ~scope_fail() noexcept(noexcept(this->_M_exit_function))
+  ~scope_fail() noexcept
   {
if (std::uncaught_exceptions() > _M_uncaught_init)
  _M_exit_function();
@@ -211,7 +211,7 @@ namespace experimental::inline fundamentals_v3
   scope_success& operator=(const scope_success&) = delete;
   scope_success& operator=(scope_success&&) = delete;
 
-  ~scope_success() noexcept(noexcept(this->_M_exit_function))
+  ~scope_success() noexcept(noexcept(this->_M_exit_function()))
   {
if (std::uncaught_exceptions() <= _M_uncaught_init)
  _M_exit_function();
diff --git a/libstdc++-v3/testsuite/experimental/scopeguard/114152.cc 
b/libstdc++-v3/testsuite/experimental/scopeguard/114152.cc
new file mode 100644
index 000..63c1f710e9f
--- /dev/null
+++ b/libstdc++-v3/testsuite/experimental/scopeguard/114152.cc
@@ -0,0 +1,24 @@
+// { dg-do compile { target c++20 } }
+
+// PR libstdc++/114152
+// Wrong exception specifiers for LFTSv3 scope guard destructors
+
+#include 
+
+using namespace std::experimental;
+
+struct F {
+  void operator()() noexcept(false);
+};
+
+static_assert( noexcept(std::declval&>().~scope_exit()) );
+static_assert( noexcept(std::declval&>().~scope_fail()) );
+static_assert( ! noexcept(std::declval&>().~scope_success()) 
);
+
+struct G {
+  void operator()() noexcept(true);
+};
+
+static_assert( noexcept(std::declval&>().~scope_exit()) );
+static_assert( noexcept(std::declval&>().~scope_fail()) );
+static_assert( noexcept(std::declval&>().~scope_success()) );
-- 
2.43.0



[committed] libstdc++: Change some URLs in the manual to use https

2024-02-28 Thread Jonathan Wakely
Pushed to trunk.

-- >8 --

libstdc++-v3/ChangeLog:

* doc/xml/manual/appendix_contributing.xml: Change URLs to use
https.
* doc/html/manual/*: Regenerate.
---
 .../doc/html/manual/appendix_contributing.html   |  8 
 libstdc++-v3/doc/html/manual/source_code_style.html  |  4 ++--
 .../doc/xml/manual/appendix_contributing.xml | 12 ++--
 3 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/libstdc++-v3/doc/xml/manual/appendix_contributing.xml 
b/libstdc++-v3/doc/xml/manual/appendix_contributing.xml
index 0dcafcb98af..ac607fcfad4 100644
--- a/libstdc++-v3/doc/xml/manual/appendix_contributing.xml
+++ b/libstdc++-v3/doc/xml/manual/appendix_contributing.xml
@@ -20,7 +20,7 @@
 
   The GNU C++ Library is part of GCC and follows the same development model,
   so the general rules for
-  http://www.w3.org/1999/xlink; 
xlink:href="http://gcc.gnu.org/contribute.html;>contributing
+  http://www.w3.org/1999/xlink; 
xlink:href="https://gcc.gnu.org/contribute.html;>contributing
   to GCC apply. Active
   contributors are assigned maintainership responsibility, and given
   write access to the source repository. First-time contributors
@@ -64,7 +64,7 @@
   

  Peruse
- the http://www.w3.org/1999/xlink; 
xlink:href="http://www.gnu.org/prep/standards/;>GNU
+ the http://www.w3.org/1999/xlink; 
xlink:href="https://www.gnu.org/prep/standards/;>GNU
  Coding Standards, and chuckle when you hit the part
  about Using Languages Other Than C.

@@ -91,7 +91,7 @@
   Assignment
 
 
-  See the http://www.w3.org/1999/xlink; 
xlink:href="http://gcc.gnu.org/contribute.html#legal;>legal 
prerequisites for all GCC contributions.
+  See the http://www.w3.org/1999/xlink; 
xlink:href="https://gcc.gnu.org/contribute.html#legal;>legal 
prerequisites for all GCC contributions.
 
 
 
@@ -155,7 +155,7 @@
  some recent commits for format and content. The
  contrib/mklog.py script can be used to
  generate a ChangeLog template for commit messages. See
- http://www.w3.org/1999/xlink; 
xlink:href="http://gcc.gnu.org/gitwrite.html;>Read-write Git access
+ http://www.w3.org/1999/xlink; 
xlink:href="https://gcc.gnu.org/gitwrite.html;>Read-write Git access
  for scripts and aliases that are useful here.

   
@@ -618,13 +618,13 @@ indicate a place that may require attention for 
multi-thread safety.
   it is intended to precede the recommendations of the GNU Coding
   Standard, which can be referenced in full here:
 
-  http://www.w3.org/1999/xlink; 
xlink:href="http://www.gnu.org/prep/standards/standards.html#Formatting;>http://www.gnu.org/prep/standards/standards.html#Formatting
+  http://www.w3.org/1999/xlink; 
xlink:href="https://www.gnu.org/prep/standards/standards.html#Formatting;>https://www.gnu.org/prep/standards/standards.html#Formatting
 
   The rest of this is also interesting reading, but skip the "Design
   Advice" part.
 
   The GCC coding conventions are here, and are also useful:
-  http://www.w3.org/1999/xlink; 
xlink:href="http://gcc.gnu.org/codingconventions.html;>http://gcc.gnu.org/codingconventions.html
+  http://www.w3.org/1999/xlink; 
xlink:href="https://gcc.gnu.org/codingconventions.html;>https://gcc.gnu.org/codingconventions.html
 
   In addition, because it doesn't seem to be stated explicitly anywhere
   else, there is an 80 column source limit.
-- 
2.43.0



[committed] libstdc++: Update outdated docs on contributing

2024-02-28 Thread Jonathan Wakely
Pushed to trunk, but I've just noticed it should be https not http.

-- >8 --

We don't want a separate ChangeLog submission now.

libstdc++-v3/ChangeLog:

* doc/xml/manual/appendix_contributing.xml: Replace outdated
info on ChangeLog entries.
* doc/html/manual/appendix_contributing.html: Regenerate.
---
 .../doc/html/manual/appendix_contributing.html   | 16 +---
 .../doc/xml/manual/appendix_contributing.xml | 16 +---
 2 files changed, 18 insertions(+), 14 deletions(-)

diff --git a/libstdc++-v3/doc/xml/manual/appendix_contributing.xml 
b/libstdc++-v3/doc/xml/manual/appendix_contributing.xml
index a9196493adc..0dcafcb98af 100644
--- a/libstdc++-v3/doc/xml/manual/appendix_contributing.xml
+++ b/libstdc++-v3/doc/xml/manual/appendix_contributing.xml
@@ -151,12 +151,12 @@
 
   

- A ChangeLog entry as plain text; see the various
- ChangeLog files for format and content. If you are
- using emacs as your editor, simply position the insertion
- point at the beginning of your change and hit CX-4a to bring
- up the appropriate ChangeLog entry. See--magic! Similar
- functionality also exists for vi.
+ A ChangeLog entry as part of the Git commit message. Check
+ some recent commits for format and content. The
+ contrib/mklog.py script can be used to
+ generate a ChangeLog template for commit messages. See
+ http://www.w3.org/1999/xlink; 
xlink:href="http://gcc.gnu.org/gitwrite.html;>Read-write Git access
+ for scripts and aliases that are useful here.

   
 
@@ -171,7 +171,7 @@
   

  The patch itself. If you are using the Git repository use
- git diff or git format-patch
+ git show or git format-patch
  to produce a patch;
  otherwise, use diff -cp OLD NEW. If your
  version of diff does not support these options, then get the
@@ -186,6 +186,8 @@
  patches and related discussion should be sent to the
  libstdc++ mailing list. In common with the rest of GCC,
  patches should also be sent to the gcc-patches mailing list.
+ So you could send your email To:libstd...@gcc.gnu.org and
+ Cc:gcc-patches@gcc.gnu.org for example.

   
 
-- 
2.43.0



[wwwdocs] Add anchor for contrib/gcc-git-customization.sh docs

2024-02-28 Thread Jonathan Wakely
I'd like to be able to link directly to this part of the page from other
docs.

OK for wwwdocs?

---
 htdocs/gitwrite.html | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/htdocs/gitwrite.html b/htdocs/gitwrite.html
index c89cdb8f..54f8005a 100644
--- a/htdocs/gitwrite.html
+++ b/htdocs/gitwrite.html
@@ -374,7 +374,7 @@ collaborators pull from there.
 
 Scripts exist in the contrib directory to help manage these spaces.
 
-contrib/gcc-git-customization.sh
+contrib/gcc-git-customization.sh
 
 This script will help set up your personal area.  It will also define
 some aliases that might be useful when developing GCC.  The script will
-- 
2.43.0



[PATCH v2] libstdc++: Fix error handling in std::print

2024-02-27 Thread Jonathan Wakely
On Tue, 27 Feb 2024 at 15:21, Tim Song wrote:
>
> [print.fun] requires a system_error, but I don't think 
> [ostream.formatted.print] does?

Yeah it looks like I got confused (again) jumping back and forth
between [print.fun] and [ostream.formatted.print]. So we're doing the
right thing, and should just add tests to verify that.
commit e1c689dbeb5b6364eb2a2f0af20ced07b8096b82
Author: Jonathan Wakely 
Date:   Thu Feb 22 13:06:59 2024

libstdc++: Test error handling in std::print

The standard requires an exception if std::print fails to write to a
FILE*. When writing to a std::ostream, failure to format the arguments
doesn't affect the stream state, but failure to write to the streadm
sets badbit.

libstdc++-v3/ChangeLog:

* testsuite/27_io/basic_ostream/print/1.cc: Check error
handling.
* testsuite/27_io/print/1.cc: Likewise.

diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/print/1.cc 
b/libstdc++-v3/testsuite/27_io/basic_ostream/print/1.cc
index 71a4daa04c9..cd4b116ac1c 100644
--- a/libstdc++-v3/testsuite/27_io/basic_ostream/print/1.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_ostream/print/1.cc
@@ -103,6 +103,40 @@ test_locale()
   }
 }
 
+void
+test_errors()
+{
+  // Failure to generate output is reported by setting badbit.
+  std::stringstream in(std::ios::in);
+  std::print(in, "{}", "nope"); // No exception here.
+  VERIFY(in.bad());
+#ifdef __cpp_exceptions
+  in.clear();
+  in.exceptions(std::ios::badbit);
+  try
+  {
+std::print(in, "{}", "nope"); // Should throw now.
+VERIFY(false);
+  }
+  catch (const std::ios::failure&)
+  {
+  }
+
+  // An exception thrown when formatting the string is propagated
+  // without setting badbit.
+  std::ostringstream out;
+  try
+  {
+std::vprint_nonunicode(out, "{}", std::make_format_args());
+VERIFY(false);
+  }
+  catch (const std::format_error&)
+  {
+  }
+  VERIFY(out.good());
+#endif
+}
+
 int main()
 {
   test_print_ostream();
@@ -111,4 +145,5 @@ int main()
   test_print_no_padding();
   test_vprint_nonunicode();
   test_locale();
+  test_errors();
 }
diff --git a/libstdc++-v3/testsuite/27_io/print/1.cc 
b/libstdc++-v3/testsuite/27_io/print/1.cc
index 6a294e0454b..d570f7938be 100644
--- a/libstdc++-v3/testsuite/27_io/print/1.cc
+++ b/libstdc++-v3/testsuite/27_io/print/1.cc
@@ -74,6 +74,21 @@ test_vprint_nonunicode()
   // { dg-output "garbage in . garbage out" }
 }
 
+void
+test_errors()
+{
+#ifdef __cpp_exceptions
+  try
+  {
+std::print(stdin, "{}", "nope");
+VERIFY(false);
+  }
+  catch (const std::system_error&)
+  {
+  }
+#endif
+}
+
 int main()
 {
   test_print_default();
@@ -82,4 +97,5 @@ int main()
   test_println_file();
   test_print_raw();
   test_vprint_nonunicode();
+  test_errors();
 }


Re: [PATCH 8/8] libstdc++: Do not define lock-free atomic aliases if not fully lock-free [PR114103]

2024-02-27 Thread Jonathan Wakely
Ooops, I forgot to add --no-numbered so these were eight unrelated
patches, not PATCH 1/8 .. PATCH 8/8. Sorry for any confusion.

On Tue, 27 Feb 2024 at 14:33, Jonathan Wakely  wrote:
>
> On Tue, 27 Feb 2024 at 11:49, Jonathan Wakely  wrote:
> >
> > Tested x86_64-linux. I think we should make this change, because
> > otherwise we define the typedefs for platforms with no lock-free
> > atomics, like hppa-hpux. Instead of lying, those typedefs should be
> > absent on that target.
> >
> > -- >8 --
> >
> > libstdc++-v3/ChangeLog:
> >
> > PR libstdc++/114103
> > * include/bits/version.def (atomic_lock_free_type_aliases): Add
> > extra_cond to check for at least one always-lock-free type.
> > * include/bits/version.h: Regenerate.
> > * include/std/atomic (atomic_signed_lock_free)
> > (atomic_unsigned_lock_free): Only use always-lock-free types.
> > ---
> >  libstdc++-v3/include/bits/version.def | 1 +
> >  libstdc++-v3/include/bits/version.h   | 2 +-
> >  libstdc++-v3/include/std/atomic   | 6 +++---
> >  3 files changed, 5 insertions(+), 4 deletions(-)
> >
> > diff --git a/libstdc++-v3/include/bits/version.def 
> > b/libstdc++-v3/include/bits/version.def
> > index 502961eb269..d298420121b 100644
> > --- a/libstdc++-v3/include/bits/version.def
> > +++ b/libstdc++-v3/include/bits/version.def
> > @@ -739,6 +739,7 @@ ftms = {
> >values = {
> >  v = 201907;
> >  cxxmin = 20;
> > +extra_cond = "(__GCC_ATOMIC_INT_LOCK_FREE | 
> > __GCC_ATOMIC_LONG_LOCK_FREE | __GCC_ATOMIC_CHAR_LOCK_FREE) & 2";
>
> Maybe this should be > 1 instead of & 2 in case there are targets that
> define it to 4 or something. I think those are only supposed to be
> defined to 0, 1, or 2 though.
>
>
> >};
> >  };
> >
> > diff --git a/libstdc++-v3/include/bits/version.h 
> > b/libstdc++-v3/include/bits/version.h
> > index 7a6fbd35e2e..9107b45a484 100644
> > --- a/libstdc++-v3/include/bits/version.h
> > +++ b/libstdc++-v3/include/bits/version.h
> > @@ -819,7 +819,7 @@
> >  #undef __glibcxx_want_atomic_float
> >
> >  #if !defined(__cpp_lib_atomic_lock_free_type_aliases)
> > -# if (__cplusplus >= 202002L)
> > +# if (__cplusplus >= 202002L) && ((__GCC_ATOMIC_INT_LOCK_FREE | 
> > __GCC_ATOMIC_LONG_LOCK_FREE | __GCC_ATOMIC_CHAR_LOCK_FREE) & 2)
> >  #  define __glibcxx_atomic_lock_free_type_aliases 201907L
> >  #  if defined(__glibcxx_want_all) || 
> > defined(__glibcxx_want_atomic_lock_free_type_aliases)
> >  #   define __cpp_lib_atomic_lock_free_type_aliases 201907L
> > diff --git a/libstdc++-v3/include/std/atomic 
> > b/libstdc++-v3/include/std/atomic
> > index 559f8370459..1462cf5ec23 100644
> > --- a/libstdc++-v3/include/std/atomic
> > +++ b/libstdc++-v3/include/std/atomic
> > @@ -1774,13 +1774,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >  = atomic>;
> >using atomic_unsigned_lock_free
> >  = atomic>;
> > -# elif ATOMIC_INT_LOCK_FREE || !(ATOMIC_LONG_LOCK_FREE || 
> > ATOMIC_CHAR_LOCK_FREE)
> > +# elif ATOMIC_INT_LOCK_FREE == 2
>
> Similarly, this could be > 1 but again, I think == 2 is OK.
>
> >using atomic_signed_lock_free = atomic;
> >using atomic_unsigned_lock_free = atomic;
> > -# elif ATOMIC_LONG_LOCK_FREE
> > +# elif ATOMIC_LONG_LOCK_FREE == 2
> >using atomic_signed_lock_free = atomic;
> >using atomic_unsigned_lock_free = atomic;
> > -# elif ATOMIC_CHAR_LOCK_FREE
> > +# elif ATOMIC_CHAR_LOCK_FREE == 2
> >using atomic_signed_lock_free = atomic;
> >using atomic_unsigned_lock_free = atomic;
> >  # else
> > --
> > 2.43.0
> >



Re: [PATCH 8/8] libstdc++: Do not define lock-free atomic aliases if not fully lock-free [PR114103]

2024-02-27 Thread Jonathan Wakely
On Tue, 27 Feb 2024 at 11:49, Jonathan Wakely  wrote:
>
> Tested x86_64-linux. I think we should make this change, because
> otherwise we define the typedefs for platforms with no lock-free
> atomics, like hppa-hpux. Instead of lying, those typedefs should be
> absent on that target.
>
> -- >8 --
>
> libstdc++-v3/ChangeLog:
>
> PR libstdc++/114103
> * include/bits/version.def (atomic_lock_free_type_aliases): Add
> extra_cond to check for at least one always-lock-free type.
> * include/bits/version.h: Regenerate.
> * include/std/atomic (atomic_signed_lock_free)
> (atomic_unsigned_lock_free): Only use always-lock-free types.
> ---
>  libstdc++-v3/include/bits/version.def | 1 +
>  libstdc++-v3/include/bits/version.h   | 2 +-
>  libstdc++-v3/include/std/atomic   | 6 +++---
>  3 files changed, 5 insertions(+), 4 deletions(-)
>
> diff --git a/libstdc++-v3/include/bits/version.def 
> b/libstdc++-v3/include/bits/version.def
> index 502961eb269..d298420121b 100644
> --- a/libstdc++-v3/include/bits/version.def
> +++ b/libstdc++-v3/include/bits/version.def
> @@ -739,6 +739,7 @@ ftms = {
>values = {
>  v = 201907;
>  cxxmin = 20;
> +extra_cond = "(__GCC_ATOMIC_INT_LOCK_FREE | __GCC_ATOMIC_LONG_LOCK_FREE 
> | __GCC_ATOMIC_CHAR_LOCK_FREE) & 2";

Maybe this should be > 1 instead of & 2 in case there are targets that
define it to 4 or something. I think those are only supposed to be
defined to 0, 1, or 2 though.


>};
>  };
>
> diff --git a/libstdc++-v3/include/bits/version.h 
> b/libstdc++-v3/include/bits/version.h
> index 7a6fbd35e2e..9107b45a484 100644
> --- a/libstdc++-v3/include/bits/version.h
> +++ b/libstdc++-v3/include/bits/version.h
> @@ -819,7 +819,7 @@
>  #undef __glibcxx_want_atomic_float
>
>  #if !defined(__cpp_lib_atomic_lock_free_type_aliases)
> -# if (__cplusplus >= 202002L)
> +# if (__cplusplus >= 202002L) && ((__GCC_ATOMIC_INT_LOCK_FREE | 
> __GCC_ATOMIC_LONG_LOCK_FREE | __GCC_ATOMIC_CHAR_LOCK_FREE) & 2)
>  #  define __glibcxx_atomic_lock_free_type_aliases 201907L
>  #  if defined(__glibcxx_want_all) || 
> defined(__glibcxx_want_atomic_lock_free_type_aliases)
>  #   define __cpp_lib_atomic_lock_free_type_aliases 201907L
> diff --git a/libstdc++-v3/include/std/atomic b/libstdc++-v3/include/std/atomic
> index 559f8370459..1462cf5ec23 100644
> --- a/libstdc++-v3/include/std/atomic
> +++ b/libstdc++-v3/include/std/atomic
> @@ -1774,13 +1774,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>  = atomic>;
>using atomic_unsigned_lock_free
>  = atomic>;
> -# elif ATOMIC_INT_LOCK_FREE || !(ATOMIC_LONG_LOCK_FREE || 
> ATOMIC_CHAR_LOCK_FREE)
> +# elif ATOMIC_INT_LOCK_FREE == 2

Similarly, this could be > 1 but again, I think == 2 is OK.

>using atomic_signed_lock_free = atomic;
>using atomic_unsigned_lock_free = atomic;
> -# elif ATOMIC_LONG_LOCK_FREE
> +# elif ATOMIC_LONG_LOCK_FREE == 2
>using atomic_signed_lock_free = atomic;
>using atomic_unsigned_lock_free = atomic;
> -# elif ATOMIC_CHAR_LOCK_FREE
> +# elif ATOMIC_CHAR_LOCK_FREE == 2
>using atomic_signed_lock_free = atomic;
>using atomic_unsigned_lock_free = atomic;
>  # else
> --
> 2.43.0
>



[PATCH 8/8] libstdc++: Do not define lock-free atomic aliases if not fully lock-free [PR114103]

2024-02-27 Thread Jonathan Wakely
Tested x86_64-linux. I think we should make this change, because
otherwise we define the typedefs for platforms with no lock-free
atomics, like hppa-hpux. Instead of lying, those typedefs should be
absent on that target.

-- >8 --

libstdc++-v3/ChangeLog:

PR libstdc++/114103
* include/bits/version.def (atomic_lock_free_type_aliases): Add
extra_cond to check for at least one always-lock-free type.
* include/bits/version.h: Regenerate.
* include/std/atomic (atomic_signed_lock_free)
(atomic_unsigned_lock_free): Only use always-lock-free types.
---
 libstdc++-v3/include/bits/version.def | 1 +
 libstdc++-v3/include/bits/version.h   | 2 +-
 libstdc++-v3/include/std/atomic   | 6 +++---
 3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/libstdc++-v3/include/bits/version.def 
b/libstdc++-v3/include/bits/version.def
index 502961eb269..d298420121b 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -739,6 +739,7 @@ ftms = {
   values = {
 v = 201907;
 cxxmin = 20;
+extra_cond = "(__GCC_ATOMIC_INT_LOCK_FREE | __GCC_ATOMIC_LONG_LOCK_FREE | 
__GCC_ATOMIC_CHAR_LOCK_FREE) & 2";
   };
 };
 
diff --git a/libstdc++-v3/include/bits/version.h 
b/libstdc++-v3/include/bits/version.h
index 7a6fbd35e2e..9107b45a484 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -819,7 +819,7 @@
 #undef __glibcxx_want_atomic_float
 
 #if !defined(__cpp_lib_atomic_lock_free_type_aliases)
-# if (__cplusplus >= 202002L)
+# if (__cplusplus >= 202002L) && ((__GCC_ATOMIC_INT_LOCK_FREE | 
__GCC_ATOMIC_LONG_LOCK_FREE | __GCC_ATOMIC_CHAR_LOCK_FREE) & 2)
 #  define __glibcxx_atomic_lock_free_type_aliases 201907L
 #  if defined(__glibcxx_want_all) || 
defined(__glibcxx_want_atomic_lock_free_type_aliases)
 #   define __cpp_lib_atomic_lock_free_type_aliases 201907L
diff --git a/libstdc++-v3/include/std/atomic b/libstdc++-v3/include/std/atomic
index 559f8370459..1462cf5ec23 100644
--- a/libstdc++-v3/include/std/atomic
+++ b/libstdc++-v3/include/std/atomic
@@ -1774,13 +1774,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 = atomic>;
   using atomic_unsigned_lock_free
 = atomic>;
-# elif ATOMIC_INT_LOCK_FREE || !(ATOMIC_LONG_LOCK_FREE || 
ATOMIC_CHAR_LOCK_FREE)
+# elif ATOMIC_INT_LOCK_FREE == 2
   using atomic_signed_lock_free = atomic;
   using atomic_unsigned_lock_free = atomic;
-# elif ATOMIC_LONG_LOCK_FREE
+# elif ATOMIC_LONG_LOCK_FREE == 2
   using atomic_signed_lock_free = atomic;
   using atomic_unsigned_lock_free = atomic;
-# elif ATOMIC_CHAR_LOCK_FREE
+# elif ATOMIC_CHAR_LOCK_FREE == 2
   using atomic_signed_lock_free = atomic;
   using atomic_unsigned_lock_free = atomic;
 # else
-- 
2.43.0



[PATCH 3/8] libstdc++: Fix std::print for Cygwin

2024-02-27 Thread Jonathan Wakely
Tested x86_64-linux. I am unable to test this on Cygwin myself. Testing
and reviews invited.

-- >8 --

Cygwin should use std::fwrite, not WriteConsoleW. And the -lstdc++exp
library is only needed when running the tests on *-*-mingw*.

libstdc++-v3/ChangeLog:

* include/std/ostream (vprint_unicode) [__CYGWIN__]: Use POSIX
code path for Cygwin instead of Windows.
* include/std/print (vprint_unicode) [__CYGWIN__]: Likewise.
* testsuite/27_io/basic_ostream/print/1.cc: Only add -lstdc++exp
for *-*-mingw* targets.
* testsuite/27_io/print/1.cc: Likewise.
---
 libstdc++-v3/include/std/ostream  | 4 ++--
 libstdc++-v3/include/std/print| 2 +-
 libstdc++-v3/testsuite/27_io/basic_ostream/print/1.cc | 2 +-
 libstdc++-v3/testsuite/27_io/print/1.cc   | 2 +-
 4 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/libstdc++-v3/include/std/ostream b/libstdc++-v3/include/std/ostream
index 7d501d67489..a136399ad0b 100644
--- a/libstdc++-v3/include/std/ostream
+++ b/libstdc++-v3/include/std/ostream
@@ -906,7 +906,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   inline void
   vprint_unicode(ostream& __os, string_view __fmt, format_args __args)
   {
-#ifndef _WIN32
+#if !defined(_WIN32) || defined(__CYGWIN__)
 // For most targets we don't need to do anything special to write
 // Unicode to a terminal.
 std::vprint_nonunicode(__os, __fmt, __args);
@@ -923,7 +923,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// If stream refers to a terminal, write a Unicode string to it.
if (auto __term = __open_terminal(__os.rdbuf()))
  {
-#ifndef _WIN32
+#if !defined(_WIN32) || defined(__CYGWIN__)
// For POSIX, __open_terminal(streambuf*) uses fdopen to open a
// new file, so we would need to close it here. This code is not
// actually compiled because it's inside an #ifdef _WIN32 group,
diff --git a/libstdc++-v3/include/std/print b/libstdc++-v3/include/std/print
index 492f333dfa6..d44033469de 100644
--- a/libstdc++-v3/include/std/print
+++ b/libstdc++-v3/include/std/print
@@ -64,7 +64,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   inline void
   vprint_unicode(FILE* __stream, string_view __fmt, format_args __args)
   {
-#ifndef _WIN32
+#if !defined(_WIN32) || defined(__CYGWIN__)
 // For most targets we don't need to do anything special to write
 // Unicode to a terminal.
 std::vprint_nonunicode(__stream, __fmt, __args);
diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/print/1.cc 
b/libstdc++-v3/testsuite/27_io/basic_ostream/print/1.cc
index b3abc570d1e..71a4daa04c9 100644
--- a/libstdc++-v3/testsuite/27_io/basic_ostream/print/1.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_ostream/print/1.cc
@@ -1,4 +1,4 @@
-// { dg-options "-lstdc++exp" }
+// { dg-additional-options "-lstdc++exp" { target { *-*-mingw* } } }
 // { dg-do run { target c++23 } }
 // { dg-require-fileio "" }
 
diff --git a/libstdc++-v3/testsuite/27_io/print/1.cc 
b/libstdc++-v3/testsuite/27_io/print/1.cc
index 3cfdac1bb74..6a294e0454b 100644
--- a/libstdc++-v3/testsuite/27_io/print/1.cc
+++ b/libstdc++-v3/testsuite/27_io/print/1.cc
@@ -1,4 +1,4 @@
-// { dg-options "-lstdc++exp" }
+// { dg-additional-options "-lstdc++exp" { target { *-*-mingw* } } }
 // { dg-do run { target c++23 } }
 // { dg-require-fileio "" }
 
-- 
2.43.0



[PATCH 5/8] libstdc++: Consistently use noexcept, constexpr, nodiscard on bitmask ops

2024-02-27 Thread Jonathan Wakely
Tested x86_64-linux. Reviews invited.

-- >8 --

The bitwise operators for combining bitmask types such as std::launch
are not consistently annotated with noexcept, constexpr, and nodiscard.

This is the subject of LWG 3977, although the proposed resolution
doesn't work. We can make the changes in libstdc++ anyway though.

libstdc++-v3/ChangeLog:

* include/bits/atomic_base.h (operator|, operator&): Add
noexcept.
* include/bits/fs_fwd.h (operator&, operator|, operator^)
(operator~): Add nodiscard to overloads for copy_options, perms,
perm_options, and directory_options.
* include/bits/ios_base.h (operator&, operator|, operator^)
(operator~): Add nodiscard and noexcept to overloads for
_Ios_Fmtflags, _Ios_Openmode, and _Ios_Iostate.
(operator|=, operator&=, operator^=): Add constexpr for C++14.
* include/bits/regex_constants.h (operator&, operator|, operator^)
(operator~): Add nodiscard and noexcept to overloads for
syntax_option_type and match_flag_type.
(operator|=, operator&=, operator^=): Add noexcept.
* include/std/charconv (operator&, operator|, operator^)
(operator~): Add nodiscard to overloads for chars_format.
* include/std/future (operator&, operator|, operator^)
(operator~): Add nodiscard for overloads for launch.
(operator&=, operator|=, operator^=): Add constexpr for C++14.
* include/experimental/bits/fs_fwd.h  (operator&, operator|)
(operator^, operator~): Add nodiscard to overloads for
copy_options, perms, and directory_options.
* testsuite/27_io/ios_base/types/fmtflags/bitmask_operators.cc:
Add dg-warning for nodiscard warnings.
* testsuite/27_io/ios_base/types/iostate/bitmask_operators.cc:
Likewise.
* testsuite/27_io/ios_base/types/openmode/bitmask_operators.cc:
Likewise.
* testsuite/27_io/filesystem/operations/bitmask_types.cc:
New test.
---
 libstdc++-v3/include/bits/atomic_base.h   |  4 +-
 libstdc++-v3/include/bits/fs_fwd.h| 16 
 libstdc++-v3/include/bits/ios_base.h  | 89 ---
 libstdc++-v3/include/bits/regex_constants.h   | 52 ++-
 .../include/experimental/bits/fs_fwd.h| 12 +++
 libstdc++-v3/include/std/charconv |  4 +
 libstdc++-v3/include/std/future   |  7 ++
 .../filesystem/operations/bitmask_types.cc| 56 
 .../types/fmtflags/bitmask_operators.cc   |  4 +
 .../types/iostate/bitmask_operators.cc|  4 +
 .../types/openmode/bitmask_operators.cc   |  4 +
 11 files changed, 194 insertions(+), 58 deletions(-)
 create mode 100644 
libstdc++-v3/testsuite/27_io/filesystem/operations/bitmask_types.cc

diff --git a/libstdc++-v3/include/bits/atomic_base.h 
b/libstdc++-v3/include/bits/atomic_base.h
index d3a2c4f3805..b857b441169 100644
--- a/libstdc++-v3/include/bits/atomic_base.h
+++ b/libstdc++-v3/include/bits/atomic_base.h
@@ -100,13 +100,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   /// @endcond
 
   constexpr memory_order
-  operator|(memory_order __m, __memory_order_modifier __mod)
+  operator|(memory_order __m, __memory_order_modifier __mod) noexcept
   {
 return memory_order(int(__m) | int(__mod));
   }
 
   constexpr memory_order
-  operator&(memory_order __m, __memory_order_modifier __mod)
+  operator&(memory_order __m, __memory_order_modifier __mod) noexcept
   {
 return memory_order(int(__m) & int(__mod));
   }
diff --git a/libstdc++-v3/include/bits/fs_fwd.h 
b/libstdc++-v3/include/bits/fs_fwd.h
index 6208e799b84..7e2bc30df30 100644
--- a/libstdc++-v3/include/bits/fs_fwd.h
+++ b/libstdc++-v3/include/bits/fs_fwd.h
@@ -91,6 +91,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
 
   /// @{
   /// @relates copy_options
+  [[nodiscard]]
   constexpr copy_options
   operator&(copy_options __x, copy_options __y) noexcept
   {
@@ -99,6 +100,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
static_cast<__utype>(__x) & static_cast<__utype>(__y));
   }
 
+  [[nodiscard]]
   constexpr copy_options
   operator|(copy_options __x, copy_options __y) noexcept
   {
@@ -107,6 +109,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
static_cast<__utype>(__x) | static_cast<__utype>(__y));
   }
 
+  [[nodiscard]]
   constexpr copy_options
   operator^(copy_options __x, copy_options __y) noexcept
   {
@@ -115,6 +118,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
static_cast<__utype>(__x) ^ static_cast<__utype>(__y));
   }
 
+  [[nodiscard]]
   constexpr copy_options
   operator~(copy_options __x) noexcept
   {
@@ -161,6 +165,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
 
   /// @{
   /// @relates perms
+  [[nodiscard]]
   constexpr perms
   operator&(perms __x, perms __y) noexcept
   {
@@ -169,6 +174,7 @@ _GLIBCXX_END_NAMESPACE_CXX11
static_cast<__utype>(__x) & static_cast<__utype>(__y));
   }
 
+  [[nodiscard]]
   constexpr perms
   operator|(perms __x, perms __y) noexcept
   {
@@ -177,6 +183,7 @@ 

[PATCH 6/8] libstdc++: Add more nodiscard uses in

2024-02-27 Thread Jonathan Wakely
Tested x86_64-linux. Reviews invited.

-- >8 --

libstdc++-v3/ChangeLog:

* include/bits/stl_bvector.h (vector::at): Add
nodiscard.
* include/bits/stl_vector.h (vector::at): Likewise.
(operator==, operator<=>, operator<, operator!=, operator>)
(operator<=, operator>=): Add nodiscard.
* testsuite/23_containers/vector/nodiscard.cc: New test.
---
 libstdc++-v3/include/bits/stl_bvector.h   |   4 +-
 libstdc++-v3/include/bits/stl_vector.h|  18 +--
 .../23_containers/vector/nodiscard.cc | 153 ++
 3 files changed, 164 insertions(+), 11 deletions(-)
 create mode 100644 libstdc++-v3/testsuite/23_containers/vector/nodiscard.cc

diff --git a/libstdc++-v3/include/bits/stl_bvector.h 
b/libstdc++-v3/include/bits/stl_bvector.h
index aa5644b4a0e..2c8b892b07a 100644
--- a/libstdc++-v3/include/bits/stl_bvector.h
+++ b/libstdc++-v3/include/bits/stl_bvector.h
@@ -1101,7 +1101,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
   }
 
 public:
-  _GLIBCXX20_CONSTEXPR
+  _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
   reference
   at(size_type __n)
   {
@@ -1109,7 +1109,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
return (*this)[__n];
   }
 
-  _GLIBCXX20_CONSTEXPR
+  _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
   const_reference
   at(size_type __n) const
   {
diff --git a/libstdc++-v3/include/bits/stl_vector.h 
b/libstdc++-v3/include/bits/stl_vector.h
index 6a9543eefce..a8d387f40a1 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -1172,7 +1172,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*  is first checked that it is in the range of the vector.  The
*  function throws out_of_range if the check fails.
*/
-  _GLIBCXX20_CONSTEXPR
+  _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
   reference
   at(size_type __n)
   {
@@ -1191,7 +1191,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*  is first checked that it is in the range of the vector.  The
*  function throws out_of_range if the check fails.
*/
-  _GLIBCXX20_CONSTEXPR
+  _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
   const_reference
   at(size_type __n) const
   {
@@ -2042,7 +2042,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*  and if corresponding elements compare equal.
   */
   template
-_GLIBCXX20_CONSTEXPR
+_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
 inline bool
 operator==(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
 { return (__x.size() == __y.size()
@@ -2061,7 +2061,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*  `<` and `>=` etc.
   */
   template
-_GLIBCXX20_CONSTEXPR
+[[nodiscard]] _GLIBCXX20_CONSTEXPR
 inline __detail::__synth3way_t<_Tp>
 operator<=>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
 {
@@ -2082,32 +2082,32 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*  See std::lexicographical_compare() for how the determination is made.
   */
   template
-inline bool
+_GLIBCXX_NODISCARD inline bool
 operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
 { return std::lexicographical_compare(__x.begin(), __x.end(),
  __y.begin(), __y.end()); }
 
   /// Based on operator==
   template
-inline bool
+_GLIBCXX_NODISCARD inline bool
 operator!=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
 { return !(__x == __y); }
 
   /// Based on operator<
   template
-inline bool
+_GLIBCXX_NODISCARD inline bool
 operator>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
 { return __y < __x; }
 
   /// Based on operator<
   template
-inline bool
+_GLIBCXX_NODISCARD inline bool
 operator<=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
 { return !(__y < __x); }
 
   /// Based on operator<
   template
-inline bool
+_GLIBCXX_NODISCARD inline bool
 operator>=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
 { return !(__x < __y); }
 #endif // three-way comparison
diff --git a/libstdc++-v3/testsuite/23_containers/vector/nodiscard.cc 
b/libstdc++-v3/testsuite/23_containers/vector/nodiscard.cc
new file mode 100644
index 000..3b5480d16d4
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/nodiscard.cc
@@ -0,0 +1,153 @@
+// { dg-do compile { target c++17 } }
+
+#include 
+
+void
+test_observers(std::vector v)
+{
+  v.size(); // { dg-warning "ignoring return value" }
+  v.capacity(); // { dg-warning "ignoring return value" }
+  v.empty(); // { dg-warning "ignoring return value" }
+}
+
+void
+test_element_access(std::vector v)
+{
+  v.front(); // { dg-warning "ignoring return value" }
+  v.back();  // { dg-warning "ignoring return value" }
+  v[1];  // { dg-warning "ignoring return value" }
+  v.at(1);   // { dg-warning "ignoring return value" }
+  v.data();  // { 

[PATCH 7/8] libstdc++: Add nodiscard in

2024-02-27 Thread Jonathan Wakely
Tested x86_64-linux. Reviews invited.

-- >8 --

libstdc++-v3/ChangeLog:

* include/bits/stl_algo.h:
* testsuite/25_algorithms/unique/1.cc: Add dg-warning.
* testsuite/25_algorithms/unique/11480.cc: Likewise.
* testsuite/25_algorithms/unique_copy/26133.cc: Likewise.
---
 libstdc++-v3/include/bits/stl_algo.h  | 38 +--
 .../testsuite/25_algorithms/unique/1.cc   |  1 +
 .../testsuite/25_algorithms/unique/11480.cc   |  2 +-
 .../25_algorithms/unique_copy/26133.cc|  2 +
 4 files changed, 23 insertions(+), 20 deletions(-)

diff --git a/libstdc++-v3/include/bits/stl_algo.h 
b/libstdc++-v3/include/bits/stl_algo.h
index 7a0cf6b6737..bbc130d3e71 100644
--- a/libstdc++-v3/include/bits/stl_algo.h
+++ b/libstdc++-v3/include/bits/stl_algo.h
@@ -320,7 +320,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  [__first1,__last1-(__last2-__first2))
   */
   template
-_GLIBCXX20_CONSTEXPR
+_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
 inline _ForwardIterator1
 find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
 _ForwardIterator2 __first2, _ForwardIterator2 __last2)
@@ -370,7 +370,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   */
   template
-_GLIBCXX20_CONSTEXPR
+_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
 inline _ForwardIterator1
 find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
 _ForwardIterator2 __first2, _ForwardIterator2 __last2,
@@ -405,7 +405,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  @p [__first,__last), and false otherwise.
   */
   template
-_GLIBCXX20_CONSTEXPR
+_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
 inline bool
 all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred)
 { return __last == std::find_if_not(__first, __last, __pred); }
@@ -423,7 +423,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  @p [__first,__last), and false otherwise.
   */
   template
-_GLIBCXX20_CONSTEXPR
+_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
 inline bool
 none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred)
 { return __last == _GLIBCXX_STD_A::find_if(__first, __last, __pred); }
@@ -442,7 +442,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  otherwise.
   */
   template
-_GLIBCXX20_CONSTEXPR
+_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
 inline bool
 any_of(_InputIterator __first, _InputIterator __last, _Predicate __pred)
 { return !std::none_of(__first, __last, __pred); }
@@ -458,7 +458,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  such that @p __pred(*i) is false, or @p __last if no such iterator 
exists.
   */
   template
-_GLIBCXX20_CONSTEXPR
+_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
 inline _InputIterator
 find_if_not(_InputIterator __first, _InputIterator __last,
_Predicate __pred)
@@ -483,7 +483,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  do not.
   */
   template
-_GLIBCXX20_CONSTEXPR
+_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
 inline bool
 is_partitioned(_InputIterator __first, _InputIterator __last,
   _Predicate __pred)
@@ -505,7 +505,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*   and @p none_of(mid, __last, __pred) are both true.
   */
   template
-_GLIBCXX20_CONSTEXPR
+_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
 _ForwardIterator
 partition_point(_ForwardIterator __first, _ForwardIterator __last,
_Predicate __pred)
@@ -572,7 +572,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  are copied is unchanged.
   */
   template
-_GLIBCXX20_CONSTEXPR
+_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
 inline _OutputIterator
 remove_copy(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, const _Tp& __value)
@@ -606,7 +606,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   */
   template
-_GLIBCXX20_CONSTEXPR
+_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
 inline _OutputIterator
 remove_copy_if(_InputIterator __first, _InputIterator __last,
   _OutputIterator __result, _Predicate __pred)
@@ -783,7 +783,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  are still present, but their value is unspecified.
   */
   template
-_GLIBCXX20_CONSTEXPR
+_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
 inline _ForwardIterator
 remove(_ForwardIterator __first, _ForwardIterator __last,
   const _Tp& __value)
@@ -817,7 +817,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  are still present, but their value is unspecified.
   */
   template
-_GLIBCXX20_CONSTEXPR
+_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
 inline _ForwardIterator
 remove_if(_ForwardIterator __first, _ForwardIterator __last,
  _Predicate __pred)
@@ -886,7 +886,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*  are still present, but their value is unspecified.
   */
   template
-_GLIBCXX20_CONSTEXPR
+_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
 inline _ForwardIterator
 

[PATCH 1/8] libstdc++: Add more [[nodiscard]] to

2024-02-27 Thread Jonathan Wakely
Tested x86_64-linux. Reviews invited.

-- >8 --

libstdc++-v3/ChangeLog:

* include/std/stacktrace: Add nodiscard attribute to all
functions without side effects.
---
 libstdc++-v3/include/std/stacktrace | 36 +
 1 file changed, 31 insertions(+), 5 deletions(-)

diff --git a/libstdc++-v3/include/std/stacktrace 
b/libstdc++-v3/include/std/stacktrace
index f570745fe51..92a69a53d98 100644
--- a/libstdc++-v3/include/std/stacktrace
+++ b/libstdc++-v3/include/std/stacktrace
@@ -75,12 +75,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 // [stacktrace.entry.obs], observers
 
+[[nodiscard]]
 constexpr native_handle_type
 native_handle() const noexcept { return _M_pc; }
 
 constexpr explicit operator bool() const noexcept { return _M_pc != -1; }
 
 // [stacktrace.entry.query], query
+[[nodiscard]]
 string
 description() const
 {
@@ -89,6 +91,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   return __s;
 }
 
+[[nodiscard]]
 string
 source_file() const
 {
@@ -97,6 +100,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   return __s;
 }
 
+[[nodiscard]]
 uint_least32_t
 source_line() const
 {
@@ -106,11 +110,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 }
 
 // [stacktrace.entry.cmp], comparison
+[[nodiscard]]
 friend constexpr bool
 operator==(const stacktrace_entry& __x,
   const stacktrace_entry& __y) noexcept
 { return __x._M_pc == __y._M_pc; }
 
+[[nodiscard]]
 friend constexpr strong_ordering
 operator<=>(const stacktrace_entry& __x,
const stacktrace_entry& __y) noexcept
@@ -384,36 +390,49 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   }
 
   // [stacktrace.basic.obs], observers
+  [[nodiscard]]
   allocator_type get_allocator() const noexcept { return _M_alloc; }
 
+  [[nodiscard]]
   const_iterator
   begin() const noexcept
   { return const_iterator{_M_impl._M_frames}; }
 
+  [[nodiscard]]
   const_iterator
   end() const noexcept
   { return begin() + size(); }
 
+  [[nodiscard]]
   const_reverse_iterator
   rbegin() const noexcept
   { return std::make_reverse_iterator(end()); }
 
+  [[nodiscard]]
   const_reverse_iterator
   rend() const noexcept
   { return std::make_reverse_iterator(begin()); }
 
-  const_iterator cbegin() const noexcept { return begin(); }
-  const_iterator cend() const noexcept { return end(); }
-  const_reverse_iterator crbegin() const noexcept { return rbegin(); };
-  const_reverse_iterator crend() const noexcept { return rend(); };
+  [[nodiscard]] const_iterator cbegin() const noexcept { return begin(); }
+  [[nodiscard]] const_iterator cend() const noexcept { return end(); }
+
+  [[nodiscard]]
+  const_reverse_iterator
+  crbegin() const noexcept { return rbegin(); };
+
+  [[nodiscard]]
+  const_reverse_iterator
+  crend() const noexcept { return rend(); };
 
   [[nodiscard]] bool empty() const noexcept { return size() == 0; }
-  size_type size() const noexcept { return _M_impl._M_size; }
+  [[nodiscard]] size_type size() const noexcept { return _M_impl._M_size; }
 
+  [[nodiscard]]
   size_type
   max_size() const noexcept
   { return _Impl::_S_max_size(_M_impl._M_alloc); }
 
+  [[nodiscard]]
   const_reference
   operator[](size_type __n) const noexcept
   {
@@ -421,6 +440,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return begin()[__n];
   }
 
+  [[nodiscard]]
   const_reference
   at(size_type __n) const
   {
@@ -431,12 +451,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   // [stacktrace.basic.cmp], comparisons
   template
+   [[nodiscard]]
friend bool
operator==(const basic_stacktrace& __x,
   const basic_stacktrace<_Allocator2>& __y) noexcept
{ return std::equal(__x.begin(), __x.end(), __y.begin(), __y.end()); }
 
   template
+   [[nodiscard]]
friend strong_ordering
operator<=>(const basic_stacktrace& __x,
const basic_stacktrace<_Allocator2>& __y) noexcept
@@ -677,6 +699,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   return __os;
 }
 
+  [[nodiscard]]
   inline string
   to_string(const stacktrace_entry& __f)
   {
@@ -686,6 +709,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   }
 
   template
+[[nodiscard]]
 string
 to_string(const basic_stacktrace<_Allocator>& __st)
 {
@@ -785,6 +809,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<>
 struct hash
 {
+  [[nodiscard]]
   size_t
   operator()(const stacktrace_entry& __f) const noexcept
   {
@@ -796,6 +821,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template
 struct hash>
 {
+  [[nodiscard]]
   size_t
   operator()(const basic_stacktrace<_Allocator>& __st) const noexcept
   {
-- 
2.43.0



[PATCH 4/8] libstdc++: Fix error handling in std::print

2024-02-27 Thread Jonathan Wakely
Tested x86_64-linux. Reviews invited.

-- >8 --

The standard requires an exception if std::print fails to write to a
std::ostream.

libstdc++-v3/ChangeLog:

* include/std/ostream (vprint_nonunicode): Throw if stream state
indicates writing failed.
* testsuite/27_io/basic_ostream/print/1.cc: Check for exception.
* testsuite/27_io/print/1.cc: Likewise.
---
 libstdc++-v3/include/std/ostream|  5 +
 .../testsuite/27_io/basic_ostream/print/1.cc| 17 +
 libstdc++-v3/testsuite/27_io/print/1.cc | 16 
 3 files changed, 38 insertions(+)

diff --git a/libstdc++-v3/include/std/ostream b/libstdc++-v3/include/std/ostream
index a136399ad0b..3740ad6edfa 100644
--- a/libstdc++-v3/include/std/ostream
+++ b/libstdc++-v3/include/std/ostream
@@ -901,6 +901,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__catch(...)
  { __os._M_setstate(ios_base::badbit); }
   }
+
+if (!__os)
+  __throw_system_error(EIO);
   }
 
   inline void
@@ -974,6 +977,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__catch(...)
  { __os._M_setstate(ios_base::badbit); }
   }
+if (!__os)
+  __throw_system_error(EIO);
 #endif // _WIN32
   }
 
diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/print/1.cc 
b/libstdc++-v3/testsuite/27_io/basic_ostream/print/1.cc
index 71a4daa04c9..14bfb14d556 100644
--- a/libstdc++-v3/testsuite/27_io/basic_ostream/print/1.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_ostream/print/1.cc
@@ -103,6 +103,22 @@ test_locale()
   }
 }
 
+void
+test_errors()
+{
+#ifdef __cpp_exceptions
+  std::stringstream in(std::ios::in);
+  try
+  {
+std::print(in, "{}", "nope");
+VERIFY(false);
+  }
+  catch (const std::system_error&)
+  {
+  }
+#endif
+}
+
 int main()
 {
   test_print_ostream();
@@ -111,4 +127,5 @@ int main()
   test_print_no_padding();
   test_vprint_nonunicode();
   test_locale();
+  test_errors();
 }
diff --git a/libstdc++-v3/testsuite/27_io/print/1.cc 
b/libstdc++-v3/testsuite/27_io/print/1.cc
index 6a294e0454b..d570f7938be 100644
--- a/libstdc++-v3/testsuite/27_io/print/1.cc
+++ b/libstdc++-v3/testsuite/27_io/print/1.cc
@@ -74,6 +74,21 @@ test_vprint_nonunicode()
   // { dg-output "garbage in . garbage out" }
 }
 
+void
+test_errors()
+{
+#ifdef __cpp_exceptions
+  try
+  {
+std::print(stdin, "{}", "nope");
+VERIFY(false);
+  }
+  catch (const std::system_error&)
+  {
+  }
+#endif
+}
+
 int main()
 {
   test_print_default();
@@ -82,4 +97,5 @@ int main()
   test_println_file();
   test_print_raw();
   test_vprint_nonunicode();
+  test_errors();
 }
-- 
2.43.0



[PATCH 2/8] libstdc++: Include in

2024-02-27 Thread Jonathan Wakely
Tested x86_64-linux. Reviews invited.

-- >8 --

libstdc++-v3/ChangeLog:

* include/bits/alloc_traits.h: Include  for
__make_move_if_noexcept_iterator.
---
 libstdc++-v3/include/bits/alloc_traits.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/libstdc++-v3/include/bits/alloc_traits.h 
b/libstdc++-v3/include/bits/alloc_traits.h
index 5e661e04741..82fc79c7b9f 100644
--- a/libstdc++-v3/include/bits/alloc_traits.h
+++ b/libstdc++-v3/include/bits/alloc_traits.h
@@ -38,6 +38,9 @@
 # if _GLIBCXX_HOSTED
 #  include 
 # endif
+# if __cpp_exceptions
+#  include  // __make_move_if_noexcept_iterator
+# endif
 #endif
 
 namespace std _GLIBCXX_VISIBILITY(default)
-- 
2.43.0



[committed] doc: Fix typos in -Wmismatched-dealloc docs

2024-02-21 Thread Jonathan Wakely
Pushed to trunk as obvious.

-- >8 --

gcc/ChangeLog:

* doc/invoke.texi (Warning Options): Fix typos.
---
 gcc/doc/invoke.texi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index d75b28484bb..b4e4ee9fb81 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -7262,7 +7262,7 @@ when non-existent profile data is justified.
 @item -Wmismatched-dealloc
 
 Warn for calls to deallocation functions with pointer arguments returned
-from from allocations functions for which the former isn't a suitable
+from allocation functions for which the former isn't a suitable
 deallocator.  A pair of functions can be associated as matching allocators
 and deallocators by use of attribute @code{malloc}.  Unless disabled by
 the @option{-fno-builtin} option the standard functions @code{calloc},
-- 
2.43.0



Re: [PATCH][_GLIBCXX_DEBUG] Fix std::__niter_base behavior

2024-02-20 Thread Jonathan Wakely
On Tue, 20 Feb 2024 at 18:43, François Dumont wrote:
>
>libstdc++: [_GLIBCXX_DEBUG] Fix std::__niter_wrap behavior
>
> In _GLIBCXX_DEBUG mode the std::__niter_base can remove 2 layers, the
> __gnu_debug::_Safe_iterator<> and the __gnu_cxx::__normal_iterator<>.
> When std::__niter_wrap is called to build a __gnu_debug::_Safe_iterator<>
> from a __gnu_cxx::__normal_iterator<> we then have a consistency issue
> as the difference between the 2 iterators will done on a __normal_iterator
> on one side and a C pointer on the other. To avoid this problem call
> std::__niter_base on both input iterators.
>
> libstdc++-v3/ChangeLog:
>
> * include/bits/stl_algobase.h (std::__niter_wrap): Add a call to
> std::__niter_base on res iterator.
>
> Tested under Linux x86_64 normal and _GLIBCXX_DEBUG modes in c++98, c++11, 
> c++17.
>
> Ok to commit ?
>

OK, thanks.



Re: Typo on GCC 14 porting_to page

2024-02-19 Thread Jonathan Wakely
On Mon, 19 Feb 2024 at 20:24, peter0x44 wrote:
>
> I was reading the GCC 14 porting to page and I noticed:
>
>   Alternatively, projects using using Autoconf could enable
> AC_USE_SYSTEM_EXTENSIONS.
>
> "using using" should be "using".
>
> I read over the rest and didn't notice anything else wrong.
>
> Thanks,
> Peter D.

Thanks. I've fixed it with the attached patch, pushed to wwwdocs.
commit d472f751802f95635997649ea7ec71e4f725aa50
Author: Jonathan Wakely 
Date:   Mon Feb 19 20:44:12 2024 +

Fix "using using" typo

diff --git a/htdocs/gcc-14/porting_to.html b/htdocs/gcc-14/porting_to.html
index 901a1653..35274691 100644
--- a/htdocs/gcc-14/porting_to.html
+++ b/htdocs/gcc-14/porting_to.html
@@ -146,7 +146,7 @@ standard C mode, which can result in implicit function 
declarations.
 To address this, the -std=c11 option can be
 dropped, -std=gnu11 can be used instead,
 or -std=c11 -D_DEFAULT_SOURCE can be used re-enable
-common extensions.  Alternatively, projects using using Autoconf
+common extensions.  Alternatively, projects using Autoconf
 could enable AC_USE_SYSTEM_EXTENSIONS.
 
 


Re: [PATCH] libstdc++, Darwin: Handle a linker warning [PR112397].

2024-02-19 Thread Jonathan Wakely
On Sun, 18 Feb 2024, 16:15 Iain Sandoe,  wrote:

> Tested on i686-darwin9, x86_64-darwin14,17,19,21,23, x86_64-linux,
> aarch64-linux-gnu,
>
> OK for trunk?
> eventual back-ports?
>

Yup, ok for all.


thanks
> Iain
>
> --- 8< ---
>
> Darwin's linker warns when we make a direct branch to code that is
> in a weak definition (citing that if a different implementation of
> the weak function is chosen by the dynamic linker this would be an
> error).
>
> As the analysis in the PR shows, this can happen when we have hot/
> cold partitioning and there is an error path that is primarily cold
> but makes use of epilogue code in the hot section.  In this simple
> case, we can easily deduce that the code is in fact safe; however
> that is not something we can realistically implement in the linker.
>
> Since the user-replaceable allocators are implemented using weak
> definitions, this is a warning that is frequently flagged up in both
> the testsuite and end-user code.
>
> The chosen solution here is to suppress the hot/cold partitioning for
> these cases (it is unlikely to impact performance much c.f. the
> actual allocation).
>
> PR target/112397
>
> libstdc++-v3/ChangeLog:
>
> * configure: Regenerate.
> * configure.ac: Detect if we are building for Darwin.
> * libsupc++/Makefile.am: If we are building for Darwin, then
> suppress hot/cold partitioning for the array allocators.
> * libsupc++/Makefile.in: Regenerated.
>
> Signed-off-by: Iain Sandoe 
> Co-authored-by: Jonathan Wakely 
> ---
>  libstdc++-v3/configure | 35 +++---
>  libstdc++-v3/configure.ac  |  6 +
>  libstdc++-v3/libsupc++/Makefile.am |  8 +++
>  libstdc++-v3/libsupc++/Makefile.in |  6 +
>  4 files changed, 47 insertions(+), 8 deletions(-)
>
> diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac
> index c68cac4f345..37396bd6ebb 100644
> --- a/libstdc++-v3/configure.ac
> +++ b/libstdc++-v3/configure.ac
> @@ -109,6 +109,12 @@ ACX_LT_HOST_FLAGS
>  AC_SUBST(enable_shared)
>  AC_SUBST(enable_static)
>  AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath =
> xyes])
> +os_is_darwin=no
> +case ${host_os} in
> +  darwin*) os_is_darwin=yes ;;
> +  *) ;;
> +esac
> +AM_CONDITIONAL([OS_IS_DARWIN], [test x${os_is_darwin} = xyes])
>
>  if test "$enable_vtable_verify" = yes; then
>predep_objects_CXX="${predep_objects_CXX}
> ${glibcxx_builddir}/../libgcc/vtv_start.o"
> diff --git a/libstdc++-v3/libsupc++/Makefile.am
> b/libstdc++-v3/libsupc++/Makefile.am
> index d0e1618507e..e151ce7a1fe 100644
> --- a/libstdc++-v3/libsupc++/Makefile.am
> +++ b/libstdc++-v3/libsupc++/Makefile.am
> @@ -132,6 +132,14 @@ atomicity_file =
> ${glibcxx_srcdir}/$(ATOMICITY_SRCDIR)/atomicity.h
>  atomicity.cc: ${atomicity_file}
> $(LN_S) ${atomicity_file} ./atomicity.cc || true
>
> +if OS_IS_DARWIN
> +# See PR 112397
> +new_opvnt.lo: new_opvnt.cc
> +   $(LTCXXCOMPILE) -fno-reorder-blocks-and-partition -I. -c $<
> +new_opvnt.o: new_opvnt.cc
> +   $(CXXCOMPILE) -fno-reorder-blocks-and-partition -I. -c $<
> +endif
> +
>  # AM_CXXFLAGS needs to be in each subdirectory so that it can be
>  # modified in a per-library or per-sub-library way.  Need to manually
>  # set this option because CONFIG_CXXFLAGS has to be after
> --
> 2.39.2 (Apple Git-143)
>
>


Re: [PATCH][_GLIBCXX_DEBUG] Fix std::__niter_base behavior

2024-02-19 Thread Jonathan Wakely
On Mon, 19 Feb 2024, 08:12 Jonathan Wakely,  wrote:

>
>
> On Mon, 19 Feb 2024, 07:08 Stephan Bergmann,  wrote:
>
>> On 2/17/24 15:14, François Dumont wrote:
>> > Thanks for the link, tested and committed.
>>
>> I assume this is the cause for the below failure now,
>>
>
> Yes, the new >= C++11 overload of __niter_base recursively unwraps
> multiple layers of wrapping, so that a safe iterator wrapping a normal
> iterator wrapping a pointer is unwrapped to just a pointer. But then
> __niter_wrap doesn't restore both layers.
>


Actually that's not the problem. __niter_wrap would restore both layers,
except that it uses __niter_base itself:

>   347 | { return __from + (__res - std::__niter_base(__from)); }
>   |   ~~~^~~~

And it seems to be getting called with the wrong types. Maybe that's just a
bug in std:: erase or maybe niter_wrap needs adjusting.

I'll check in a couple of hours if François doesn't get to it first.

I have to wonder how this wasn't caught by existing tests though.


Re: [PATCH][_GLIBCXX_DEBUG] Fix std::__niter_base behavior

2024-02-19 Thread Jonathan Wakely
On Mon, 19 Feb 2024, 07:08 Stephan Bergmann,  wrote:

> On 2/17/24 15:14, François Dumont wrote:
> > Thanks for the link, tested and committed.
>
> I assume this is the cause for the below failure now,
>

Yes, the new >= C++11 overload of __niter_base recursively unwraps multiple
layers of wrapping, so that a safe iterator wrapping a normal iterator
wrapping a pointer is unwrapped to just a pointer. But then __niter_wrap
doesn't restore both layers.

I think the change might need to be reverted.




> > $ cat test.cc
> > #include 
> > #include 
> > void f(std::vector , void const * p) {
> > std::erase(v, p);
> > }
>
> > $ ~/gcc/inst/bin/g++ -std=c++20 -D_GLIBCXX_DEBUG -fsyntax-only test.cc
> > In file included from ~/gcc/inst/include/c++/14.0.1/algorithm:60,
> >  from test.cc:1:
> > ~/gcc/inst/include/c++/14.0.1/bits/stl_algobase.h: In instantiation of
> ‘constexpr _From std::__niter_wrap(_From, _To) [with _From =
> __gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator __cxx1998::vector > >,
> __debug::vector, random_access_iterator_tag>; _To =
> __gnu_cxx::__normal_iterator allocator > >]’:
> > ~/gcc/inst/include/c++/14.0.1/vector:144:29:   required from ‘constexpr
> typename std::__debug::vector<_Tp, _Allocator>::size_type
> std::erase(__debug::vector<_Tp, _Alloc>&, const _Up&) [with _Tp = const
> void*; _Alloc = allocator; _Up = const void*; typename
> __debug::vector<_Tp, _Allocator>::size_type = long unsigned int]’
> >   144 |   __cont.erase(__niter_wrap(__cont.begin(), __removed),
> >   |^~~
> > test.cc:4:15:   required from here
> > 4 | std::erase(v, p);
> >   | ~~^~
> > ~/gcc/inst/include/c++/14.0.1/bits/stl_algobase.h:347:30: error: no
> match for ‘operator-’ (operand types are
> ‘__gnu_cxx::__normal_iterator void*, std::allocator > >’ and ‘const void**’)
> >   347 | { return __from + (__res - std::__niter_base(__from)); }
> >   |   ~~~^~~~
> > In file included from
> ~/gcc/inst/include/c++/14.0.1/bits/stl_algobase.h:67:
> > ~/gcc/inst/include/c++/14.0.1/bits/stl_iterator.h:1148:7: note:
> candidate: ‘constexpr __gnu_cxx::__normal_iterator<_Iterator, _Container>
> __gnu_cxx::__normal_iterator<_Iterator,
> _Container>::operator-(difference_type) const [with _Iterator = const
> void**; _Container = std::__cxx1998::vector std::allocator >; difference_type = long int]’ (near match)
> >  1148 |   operator-(difference_type __n) const _GLIBCXX_NOEXCEPT
> >   |   ^~~~
> > ~/gcc/inst/include/c++/14.0.1/bits/stl_iterator.h:1148:7: note:
>  conversion of argument 1 would be ill-formed:
> > ~/gcc/inst/include/c++/14.0.1/bits/stl_algobase.h:347:49: error: invalid
> conversion from ‘const void**’ to ‘__gnu_cxx::__normal_iterator void**, std::__cxx1998::vector >
> >::difference_type’ {aka ‘long int’} [-fpermissive]
> >   347 | { return __from + (__res - std::__niter_base(__from)); }
> >   |~^~~~
> >   | |
> >   | const void**
> > ~/gcc/inst/include/c++/14.0.1/bits/stl_iterator.h:618:5: note:
> candidate: ‘template constexpr decltype
> ((__y.base() - __x.base())) std::operator-(const
> reverse_iterator<_IteratorL>&, const reverse_iterator<_IteratorR>&)’
> >   618 | operator-(const reverse_iterator<_IteratorL>& __x,
> >   | ^~~~
> > ~/gcc/inst/include/c++/14.0.1/bits/stl_iterator.h:618:5: note:
>  template argument deduction/substitution failed:
> > ~/gcc/inst/include/c++/14.0.1/bits/stl_algobase.h:347:30: note:
>  ‘__gnu_cxx::__normal_iterator void*, std::allocator > >’ is not derived from ‘const
> std::reverse_iterator<_IteratorL>’
> >   347 | { return __from + (__res - std::__niter_base(__from)); }
> >   |   ~~~^~~~
> > ~/gcc/inst/include/c++/14.0.1/bits/stl_iterator.h:1789:5: note:
> candidate: ‘template constexpr decltype
> ((__x.base() - __y.base())) std::operator-(const
> move_iterator<_IteratorL>&, const move_iterator<_IteratorR>&)’
> >  1789 | operator-(const move_iterator<_IteratorL>& __x,
> >   | ^~~~
> > ~/gcc/inst/include/c++/14.0.1/bits/stl_iterator.h:1789:5: note:
>  template argument deduction/substitution failed:
> > ~/gcc/inst/include/c++/14.0.1/bits/stl_algobase.h:347:30: note:
>  ‘__gnu_cxx::__normal_iterator void*, std::allocator > >’ is not derived from ‘const
> std::move_iterator<_IteratorL>’
> >   347 | { return __from + (__res - std::__niter_base(__from)); }
> >   |   ~~~^~~~
> > ~/gcc/inst/include/c++/14.0.1/bits/stl_iterator.h:1312:5: note:
> candidate: ‘template
> constexpr decltype ((__lhs.base() - __rhs.base()))
> __gnu_cxx::operator-(const __normal_iterator<_IteratorL, _Container>&,
> 

[committed] libstdc++: Fix FAIL: 26_numerics/random/pr60037-neg.cc again [PR113961]

2024-02-16 Thread Jonathan Wakely
I had another change to  in my local tree which affected
the second dg-error and I "fixed" it unnecessarily. I've tested with a
clean tree this time.

Tested aarch64-linux. Pushed to trunk.

-- >8 --

PR libstdc++/87744
PR libstdc++/113961

libstdc++-v3/ChangeLog:

* testsuite/26_numerics/random/pr60037-neg.cc: Adjust dg-error
line number.
---
 libstdc++-v3/testsuite/26_numerics/random/pr60037-neg.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libstdc++-v3/testsuite/26_numerics/random/pr60037-neg.cc 
b/libstdc++-v3/testsuite/26_numerics/random/pr60037-neg.cc
index 9d6925fb416..3c5aa7feefc 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/pr60037-neg.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/pr60037-neg.cc
@@ -12,4 +12,4 @@ auto x = std::generate_canonical

Re: [PATCH] libstdc++: atomic: Add missing clear_padding in __atomic_float constructor

2024-02-16 Thread Jonathan Wakely
On Fri, 16 Feb 2024 at 14:10, Jakub Jelinek wrote:
>
> On Fri, Feb 16, 2024 at 01:51:54PM +, Jonathan Wakely wrote:
> > Ah, although __atomic_compare_exchange only takes pointers, the
> > compiler replaces that with a call to __atomic_compare_exchange_n
> > which takes the newval by value, which presumably uses an 80-bit FP
> > register and so the padding bits become indeterminate again.
>
> __atomic_compare_exchange_n only works with integers, so I guess
> it is doing VIEW_CONVERT_EXPR (aka union-style type punning) on the
> argument.
>
> Do you have preprocessed source for the testcase?

Sent offlist.



Re: [PATCH] libstdc++: atomic: Add missing clear_padding in __atomic_float constructor

2024-02-16 Thread Jonathan Wakely
On Fri, 16 Feb 2024 at 12:38, Jonathan Wakely  wrote:
>
> On Fri, 2 Feb 2024 at 16:52, xndcn  wrote:
> >
> > Thank you for your careful review!
> >
> > > But we don't need a new one if it's going to be used in exactly one test 
> > > and if the new option does the same thing for all targets that run the 
> > > test.
> > Got it, thanks. Now add option "-latomic" directly, but it still rely
> > on the trick "[atomic_link_flags [get_multilibs]]"
> >
> > > No, because the patch is supposed to prevent the infinite loop, and so 
> > > there's no need to stop it looping after 10s. It won't loop at all.
> > Thanks, deleted.
> >
> > > We only need to clear padding for long double, not float and double, 
> > > right?
> > Yes, actually there is a check "if constexpr
> > (__atomic_impl::__maybe_has_padding<_Fp>())".
> > But "__atomic_impl::__clear_padding(_M_fp); " is indeed simply, so fixed 
> > here.
> >
> > > Why can't we run this on all targets?
> > Got it, now target option deleted.
> >
> > > There's no reason to use __builtin_memset here, just include  
> > > and use std::memcpy.
> > Thanks, fixed.
> >
> > > It definitely does have padding, just say "long double has padding bits 
> > > on x86"
> > Thanks, fixed.
> >
> > So here comes the latest patch:
>
>
> Thanks. I've applied the patch to my tree, but the new test fails
> pretty reliably.
>
> The infinite loop in std::atomic::fetch_add is fixed by
> clearing padding in the constructor, but the test fails on the
> compare_exchange_weak or compare_exchange_strong lines here:
>
>
> > +as.fetch_add(t);
> > +long double s = f + t;
> > +t = as.load();
> > +VERIFY(s == t); // padding ignored on float comparing
> > +fill_padding(s);
> > +VERIFY(as.compare_exchange_weak(s, f)); // padding cleared on cmpexchg
> > +fill_padding(f);
> > +VERIFY(as.compare_exchange_strong(f, t)); // padding cleared on 
> > cmpexchg
> >
>
>
> I think the problem is here in __atomic_impl::__compare_exchange:
>
>if (__atomic_compare_exchange(__pval, __pexp, __pi,
>   __is_weak, int(__s), int(__f)))
>  return true;
>
> Even though padding in *__pexp and *__pi has been cleared, the value
> of *__pval after a successful __atomic_compare_exchange has non-zero
> padding. That means that the next compare_exchange will fail, because
> we assume that the stored value always has zeroed padding bits.
>
> Here's a gdb session showing that __atomic_compare_exchange stores a
> value with non-zero padding:
>
> Breakpoint 2, test01 () at compare_exchange_padding.cc:43
> 43long double s2 = s;
> (gdb) n
> 44fill_padding(s2);
> (gdb)
> 45while (!as.compare_exchange_weak(s2, f)) // padding cleared
> on compexchg
> (gdb) p/x as._M_fp
> $11 = 0x40008000
> (gdb) step
> std::__atomic_float::compare_exchange_weak
> (this=0x7fffd8c0, __expected=@0x7fffd8a0: 2, __desired=0.5,
> __order=std::memory_order::seq_cst) at
> /home/jwakely/gcc/14/include/c++/14.0.1/bits/atomic_base.h:1387
> 1387return compare_exchange_weak(__expected, __desired, __order,
> (gdb) step
> std::__atomic_float::compare_exchange_weak
> (this=0x7fffd8c0, __expected=@0x7fffd8a0: 2, __desired=0.5,
> __success=std::memory_order::seq_cst,
> __failure=std::memory_order::seq_cst) at
> /home/jwakely/gcc/14/include/c++/14.0.1/bits/atomic_base.h:1347
> 1347return __atomic_impl::compare_exchange_weak(&_M_fp,
> (gdb) step
> std::__atomic_impl::compare_exchange_weak
> (__check_padding=false, __failure=std::memory_order::seq_cst,
> __success=std::memory_order::seq_cst, __desired=0.5,
> __expected=@0x7fffd8a0: 2, __ptr=0x7fffd8c0)
> at /home/jwakely/gcc/14/include/c++/14.0.1/bits/atomic_base.h:1123
> 1123return __atomic_impl::__compare_exchange<_AtomicRef>(
> (gdb)
> std::__atomic_impl::__compare_exchange
> (__f=std::memory_order::seq_cst, __s=std::memory_order::seq_cst,
> __is_weak=true,
> __i=, __e=@0x7fffd8a0: 2,
> __val=@0x7fffd8c0: 2) at
> /home/jwakely/gcc/14/include/c++/14.0.1/bits/atomic_base.h:994
> 994 __glibcxx_assert(__is_valid_cmpexch_failure_order(__f));
> (gdb) n
> 997 _Tp* const __pval = std::__addressof(__val);
> (gdb)
> 1008_Vp* const __pi = __atomic_impl::__clear_padding(__i);
> (gdb)
> 1010_Vp __exp = __e;
> (gdb)
> 1012

Re: [PATCH] libstdc++: atomic: Add missing clear_padding in __atomic_float constructor

2024-02-16 Thread Jonathan Wakely
On Fri, 2 Feb 2024 at 16:52, xndcn  wrote:
>
> Thank you for your careful review!
>
> > But we don't need a new one if it's going to be used in exactly one test 
> > and if the new option does the same thing for all targets that run the test.
> Got it, thanks. Now add option "-latomic" directly, but it still rely
> on the trick "[atomic_link_flags [get_multilibs]]"
>
> > No, because the patch is supposed to prevent the infinite loop, and so 
> > there's no need to stop it looping after 10s. It won't loop at all.
> Thanks, deleted.
>
> > We only need to clear padding for long double, not float and double, right?
> Yes, actually there is a check "if constexpr
> (__atomic_impl::__maybe_has_padding<_Fp>())".
> But "__atomic_impl::__clear_padding(_M_fp); " is indeed simply, so fixed here.
>
> > Why can't we run this on all targets?
> Got it, now target option deleted.
>
> > There's no reason to use __builtin_memset here, just include  and 
> > use std::memcpy.
> Thanks, fixed.
>
> > It definitely does have padding, just say "long double has padding bits on 
> > x86"
> Thanks, fixed.
>
> So here comes the latest patch:


Thanks. I've applied the patch to my tree, but the new test fails
pretty reliably.

The infinite loop in std::atomic::fetch_add is fixed by
clearing padding in the constructor, but the test fails on the
compare_exchange_weak or compare_exchange_strong lines here:


> +as.fetch_add(t);
> +long double s = f + t;
> +t = as.load();
> +VERIFY(s == t); // padding ignored on float comparing
> +fill_padding(s);
> +VERIFY(as.compare_exchange_weak(s, f)); // padding cleared on cmpexchg
> +fill_padding(f);
> +VERIFY(as.compare_exchange_strong(f, t)); // padding cleared on cmpexchg
>


I think the problem is here in __atomic_impl::__compare_exchange:

   if (__atomic_compare_exchange(__pval, __pexp, __pi,
  __is_weak, int(__s), int(__f)))
 return true;

Even though padding in *__pexp and *__pi has been cleared, the value
of *__pval after a successful __atomic_compare_exchange has non-zero
padding. That means that the next compare_exchange will fail, because
we assume that the stored value always has zeroed padding bits.

Here's a gdb session showing that __atomic_compare_exchange stores a
value with non-zero padding:

Breakpoint 2, test01 () at compare_exchange_padding.cc:43
43long double s2 = s;
(gdb) n
44fill_padding(s2);
(gdb)
45while (!as.compare_exchange_weak(s2, f)) // padding cleared
on compexchg
(gdb) p/x as._M_fp
$11 = 0x40008000
(gdb) step
std::__atomic_float::compare_exchange_weak
(this=0x7fffd8c0, __expected=@0x7fffd8a0: 2, __desired=0.5,
__order=std::memory_order::seq_cst) at
/home/jwakely/gcc/14/include/c++/14.0.1/bits/atomic_base.h:1387
1387return compare_exchange_weak(__expected, __desired, __order,
(gdb) step
std::__atomic_float::compare_exchange_weak
(this=0x7fffd8c0, __expected=@0x7fffd8a0: 2, __desired=0.5,
__success=std::memory_order::seq_cst,
__failure=std::memory_order::seq_cst) at
/home/jwakely/gcc/14/include/c++/14.0.1/bits/atomic_base.h:1347
1347return __atomic_impl::compare_exchange_weak(&_M_fp,
(gdb) step
std::__atomic_impl::compare_exchange_weak
(__check_padding=false, __failure=std::memory_order::seq_cst,
__success=std::memory_order::seq_cst, __desired=0.5,
__expected=@0x7fffd8a0: 2, __ptr=0x7fffd8c0)
at /home/jwakely/gcc/14/include/c++/14.0.1/bits/atomic_base.h:1123
1123return __atomic_impl::__compare_exchange<_AtomicRef>(
(gdb)
std::__atomic_impl::__compare_exchange
(__f=std::memory_order::seq_cst, __s=std::memory_order::seq_cst,
__is_weak=true,
__i=, __e=@0x7fffd8a0: 2,
__val=@0x7fffd8c0: 2) at
/home/jwakely/gcc/14/include/c++/14.0.1/bits/atomic_base.h:994
994 __glibcxx_assert(__is_valid_cmpexch_failure_order(__f));
(gdb) n
997 _Tp* const __pval = std::__addressof(__val);
(gdb)
1008_Vp* const __pi = __atomic_impl::__clear_padding(__i);
(gdb)
1010_Vp __exp = __e;
(gdb)
1012_Vp* const __pexp = __atomic_impl::__clear_padding(__exp);
(gdb)
1016if (__atomic_compare_exchange(__pval, __pexp, __pi,
(gdb) p/x *__pval
$12 = 0x40008000
(gdb) p/x *__pexp
$13 = 0x40008000
(gdb) p/x *__pi
$14 = 0x3ffe8000
(gdb) n
1018  return true;
(gdb) p/x *__pval
$15 = 0x77bf3ffe8000
(gdb)

We stored *__pi which has zero padding, but the result in *__pval has
non-zero padding. This doesn't seem to be gdb being misleading by
loading *__pval into a FP register which doesn't preserve the zero
padding, because if I do this then it fails:

  as.fetch_add(t);
  VERIFY(as.load() == s);
  __builtin_clear_padding();
  VERIFY( std::memcmp(, , sizeof(s)) == 0 );

So the value stored by fetch_add (which uses compare_exchange_weak in
a loop) really doesn't have 

[committed] libstdc++: Fix FAIL: 26_numerics/random/pr60037-neg.cc [PR113931]

2024-02-16 Thread Jonathan Wakely
Tested x86_64-linux, pushed to trunk.

-- >8 --

PR libstdc++/87744
PR libstdc++/113931

libstdc++-v3/ChangeLog:

* testsuite/26_numerics/random/pr60037-neg.cc: Adjust dg-error
line number.
---
 libstdc++-v3/testsuite/26_numerics/random/pr60037-neg.cc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/testsuite/26_numerics/random/pr60037-neg.cc 
b/libstdc++-v3/testsuite/26_numerics/random/pr60037-neg.cc
index 4c24e56cea2..9d6925fb416 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/pr60037-neg.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/pr60037-neg.cc
@@ -10,6 +10,6 @@ std::__detail::_Adaptor 
aurng(urng);
 auto x = std::generate_canonical::digits>(urng);
 
-// { dg-error "static assertion failed: template argument must be a floating 
point type" "" { target *-*-* } 271 }
+// { dg-error "static assertion failed: template argument must be a floating 
point type" "" { target *-*-* } 270 }
 
-// { dg-error "static assertion failed: template argument must be a floating 
point type" "" { target *-*-* } 3351 }
+// { dg-error "static assertion failed: template argument must be a floating 
point type" "" { target *-*-* } 3350 }
-- 
2.43.0



[committed] libstdc++: Improve docs for debug mode backtraces

2024-02-16 Thread Jonathan Wakely
Pushed to trunk.

-- >8 --

The configure option is no longer necessary.

libstdc++-v3/ChangeLog:

* doc/xml/manual/debug_mode.xml: Update docs for backtraces.
* doc/html/manual/debug_mode_using.html: Regenerate.
---
 libstdc++-v3/doc/html/manual/debug_mode_using.html | 9 -
 libstdc++-v3/doc/xml/manual/debug_mode.xml | 9 -
 2 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/libstdc++-v3/doc/html/manual/debug_mode_using.html 
b/libstdc++-v3/doc/html/manual/debug_mode_using.html
index e26d06c9179..70d6692f514 100644
--- a/libstdc++-v3/doc/html/manual/debug_mode_using.html
+++ b/libstdc++-v3/doc/html/manual/debug_mode_using.html
@@ -10,11 +10,10 @@
   78 characters.  The environment variable
   GLIBCXX_DEBUG_MESSAGE_LENGTH can be used to 
request a
   different length.Note that libstdc++ is able to produce backtraces on 
error.
-  It requires that you configure libstdc++ build with
-  --enable-libstdcxx-backtrace=yes.
-  Use -D_GLIBCXX_DEBUG_BACKTRACE to activate it.
-  You'll then have to link with libstdc++_libbacktrace static library
-  (-lstdc++_libbacktrace) to build your 
application.Using a Specific Debug 
ContainerWhen it is not feasible to recompile your 
entire application, or
+  To enable these, compile with -D_GLIBCXX_DEBUG_BACKTRACE
+  and then link with -lstdc++exp.
+  These backtraces are not supported on all platforms.
+Using a Specific Debug 
ContainerWhen it is not feasible to recompile your 
entire application, or
   only specific containers need checking, debugging containers are
   available as GNU extensions. These debugging containers are
   functionally equivalent to the standard drop-in containers used in
diff --git a/libstdc++-v3/doc/xml/manual/debug_mode.xml 
b/libstdc++-v3/doc/xml/manual/debug_mode.xml
index ac15ef6f6d0..a12158fa03e 100644
--- a/libstdc++-v3/doc/xml/manual/debug_mode.xml
+++ b/libstdc++-v3/doc/xml/manual/debug_mode.xml
@@ -162,11 +162,10 @@ which always works correctly.
   different length.
 
 Note that libstdc++ is able to produce backtraces on error.
-  It requires that you configure libstdc++ build with
-  --enable-libstdcxx-backtrace=yes.
-  Use -D_GLIBCXX_DEBUG_BACKTRACE to activate it.
-  You'll then have to link against libstdc++exp static library
-  (-lstdc++exp) to build your application.
+  To enable these, compile with -D_GLIBCXX_DEBUG_BACKTRACE
+  and then link with -lstdc++exp.
+  These backtraces are not supported on all platforms.
+
 
 
 Using a Specific Debug Container
-- 
2.43.0



[committed] libstdc++: Fix spelling of elements in manual

2024-02-16 Thread Jonathan Wakely
Pushed to trunk.

-- >8 --

libstdc++-v3/ChangeLog:

* doc/xml/manual/test.xml: Fix spelling of  elements.
* doc/html/manual/test.html: Regenerate.
---
 libstdc++-v3/doc/html/manual/test.html | 4 ++--
 libstdc++-v3/doc/xml/manual/test.xml   | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/libstdc++-v3/doc/html/manual/test.html 
b/libstdc++-v3/doc/html/manual/test.html
index 4b7f60c9bad..3657997fad4 100644
--- a/libstdc++-v3/doc/html/manual/test.html
+++ b/libstdc++-v3/doc/html/manual/test.html
@@ -356,7 +356,7 @@ cat 27_io/objects/char/3_xin.in | a.outDEJAGNU environment variable will cause every 
test to
   be run three times, using a different -std 
each time.
   Alternatively, a list of standard versions to test with can be specified
-  as a comma-separated list in the envvarGLIBCXX_TESTSUITE_STDS/envvar
+  as a comma-separated list in the GLIBCXX_TESTSUITE_STDS
   environment variable.
 
   To run the libstdc++ test suite under the
@@ -478,7 +478,7 @@ cat 27_io/objects/char/3_xin.in | a.out-std=gnu++11
 or -std=c++11 is explicitly specified, either 
via a
 target board, the v3_std_list dejagnu 
variable,
-or the envvarGLIBCXX_TESTSUITE_STDS/envvar environment 
variable.
+or the GLIBCXX_TESTSUITE_STDS environment 
variable.
 For tests that require a specific standard it is useful to also add a
 dg-options directive:
 // { dg-options "-std=gnu++11" }
diff --git a/libstdc++-v3/doc/xml/manual/test.xml 
b/libstdc++-v3/doc/xml/manual/test.xml
index f2c709bc6bf..40926946fe7 100644
--- a/libstdc++-v3/doc/xml/manual/test.xml
+++ b/libstdc++-v3/doc/xml/manual/test.xml
@@ -604,7 +604,7 @@ cat 27_io/objects/char/3_xin.in | a.out
   DEJAGNU environment variable will cause every test to
   be run three times, using a different -std each time.
   Alternatively, a list of standard versions to test with can be specified
-  as a comma-separated list in the GLIBCXX_TESTSUITE_STDS
+  as a comma-separated list in the GLIBCXX_TESTSUITE_STDS
   environment variable.
 
 
@@ -779,7 +779,7 @@ cat 27_io/objects/char/3_xin.in | a.out
 the test will be skipped by default unless -std=gnu++11
 or -std=c++11 is explicitly specified, either via a
 target board, the v3_std_list dejagnu variable,
-or the GLIBCXX_TESTSUITE_STDS environment variable.
+or the GLIBCXX_TESTSUITE_STDS environment variable.
 For tests that require a specific standard it is useful to also add a
 dg-options directive:
 // { dg-options "-std=gnu++11" }
-- 
2.43.0



  1   2   3   4   5   6   7   8   9   10   >