On Thu, 28 May 2026, 23:11 Nathan Myers, <[email protected]> wrote:
>
> __STDCPP_DEFAULT_NEW_ALIGNMENT__ is mentioned in several places
> not guarded with "#if __cpp_aligned_new". This patch fixes all
> except std/generator, the topic of PR125483.
>
> libstdc++-v3/ChangeLog:
> * include/bits/basic_string.tcc: Add #if __cpp_aligned_new.
> * src/c++17/fs_path.cc: Same.
> * testsuite/20_util/allocator/allocate_at_least.cc: Same.
> * testsuite/21_strings/basic_string/capacity/char/18654.cc: Same.
> * testsuite/21_strings/basic_string/capacity/wchar_t/18654.cc: Same.
> * testsuite/21_strings/basic_string/capacity/wchar_t/2.cc: Same.
> * testsuite/23_containers/vector/capacity/shrink_to_fit.cc: Same.
> * testsuite/23_containers/vector/capacity/shrink_to_fit2.cc: Same.
> * testsuite/23_containers/vector/modifiers/emplace/self_emplace.cc:
> Same.
> * testsuite/25_algorithms/stable_sort/overaligned.cc: Same.
> ---
> libstdc++-v3/include/bits/basic_string.tcc | 2 +-
> libstdc++-v3/src/c++17/fs_path.cc | 5 +++++
> .../testsuite/20_util/allocator/allocate_at_least.cc | 2 ++
> .../testsuite/21_strings/basic_string/capacity/char/18654.cc | 2 +-
> .../21_strings/basic_string/capacity/wchar_t/18654.cc | 2 +-
> .../testsuite/21_strings/basic_string/capacity/wchar_t/2.cc | 2 +-
> .../testsuite/23_containers/vector/capacity/shrink_to_fit.cc | 2 +-
> .../23_containers/vector/capacity/shrink_to_fit2.cc | 4 ++--
> .../23_containers/vector/modifiers/emplace/self_emplace.cc | 4 ++--
> .../testsuite/25_algorithms/stable_sort/overaligned.cc | 4 ++++
> 10 files changed, 20 insertions(+), 9 deletions(-)
>
> diff --git a/libstdc++-v3/include/bits/basic_string.tcc
> b/libstdc++-v3/include/bits/basic_string.tcc
> index 64c99fbb9d6..36d77c9d211 100644
> --- a/libstdc++-v3/include/bits/basic_string.tcc
> +++ b/libstdc++-v3/include/bits/basic_string.tcc
> @@ -445,7 +445,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> return;
> }
> #if __cpp_exceptions
> -#ifdef __glibcxx_allocate_at_least // C++23
> +#if defined(__glibcxx_allocate_at_least) && __cpp_aligned_new // C++23
> const size_type __limit =
> (__STDCPP_DEFAULT_NEW_ALIGNMENT__ - 1) / sizeof(_CharT);
> #else
I don't think we should be using this at all here. It assumes that the
allocator is std::allocator, which might be wrong.
So maybe this function should have just been changed to use
_S_allocate_at_least and not use any __limit.
> diff --git a/libstdc++-v3/src/c++17/fs_path.cc
> b/libstdc++-v3/src/c++17/fs_path.cc
> index 763d5609c7f..16abf6b8702 100644
> --- a/libstdc++-v3/src/c++17/fs_path.cc
> +++ b/libstdc++-v3/src/c++17/fs_path.cc
> @@ -264,8 +264,13 @@ struct path::_List::_Impl
> = std::max(size_t(4), alignof(value_type));
>
> // Only use aligned new if needed, because it might be less efficient.
> +#if __cpp_aligned_new
> static constexpr bool use_aligned_new
> = __STDCPP_DEFAULT_NEW_ALIGNMENT__ < required_alignment;
> +#else
> + static constexpr bool use_aligned_new = false;
> +#endif
This fs_path.cc change isn't needed. We control the flags used to
build the library. Our headers should work with the user's flags, the
library code doesn't need to. If somebody tries to build the library
with dumb options, they get to keep both pieces.
> + };
>
> // Clear the lowest two bits from the pointer (i.e. remove the _Type value)
> static _Impl* notype(_Impl* p)
> diff --git a/libstdc++-v3/testsuite/20_util/allocator/allocate_at_least.cc
> b/libstdc++-v3/testsuite/20_util/allocator/allocate_at_least.cc
> index 987e2472490..c0ee6f1e512 100644
> --- a/libstdc++-v3/testsuite/20_util/allocator/allocate_at_least.cc
> +++ b/libstdc++-v3/testsuite/20_util/allocator/allocate_at_least.cc
> @@ -66,6 +66,7 @@ void base()
>
> void extra()
> {
> +#if __cpp_aligned_new
> using SatC = std::allocator_traits<std::allocator<char>>;
> std::allocator<char> satc;
> {
> @@ -162,6 +163,7 @@ void extra()
> VERIFY(n == __STDCPP_DEFAULT_NEW_ALIGNMENT__);
> SatAnm1::deallocate(satanm1, p, n);
> }
> +#endif // __cpp_aligned_new
> }
>
> int main()
> diff --git
> a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/18654.cc
> b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/18654.cc
> index 59012a1c170..3e743db8d9d 100644
> --- a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/18654.cc
> +++ b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/char/18654.cc
> @@ -58,7 +58,7 @@ void test01()
> #else
> str.shrink_to_fit(); // reserve is deprecated in C++20
> #endif
> -#if __glibcxx_allocate_at_least
> +#if __glibcxx_allocate_at_least && __cpp_aligned_new
> unsigned limit = __STDCPP_DEFAULT_NEW_ALIGNMENT__ - 1;
> #else
I think a different change will be needed here if string::reserve()
change, right?
> unsigned limit = 0;
> diff --git
> a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/18654.cc
> b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/18654.cc
> index bf3b8dd5581..00dedea82ce 100644
> --- a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/18654.cc
> +++ b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/18654.cc
> @@ -59,7 +59,7 @@ void test01()
> #else
> str.shrink_to_fit(); // reserve is deprecated in C++20
> #endif
> -#if __glibcxx_allocate_at_least
> +#if __glibcxx_allocate_at_least && __cpp_aligned_new
> unsigned limit = __STDCPP_DEFAULT_NEW_ALIGNMENT__ / sizeof(wchar_t) -
> 1;
> #else
> unsigned limit = 0;
> diff --git
> a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/2.cc
> b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/2.cc
> index 04a3763fc77..3c3c32c7dec 100644
> --- a/libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/2.cc
> +++ b/libstdc++-v3/testsuite/21_strings/basic_string/capacity/wchar_t/2.cc
> @@ -36,7 +36,7 @@ void test02()
> // These are not guaranteed to absolutely minimize storage.
> // allocator<wchar_t>::allocate_at_least rounds up to what
> // it knows ::op new delivers.
> -#ifdef __glibcxx_allocate_at_least
> +#if __glibcxx_allocate_at_least && __cpp_aligned_new
> unsigned limit = __STDCPP_DEFAULT_NEW_ALIGNMENT__ / sizeof(wchar_t) - 1;
> #else
> unsigned limit = 0;
> diff --git
> a/libstdc++-v3/testsuite/23_containers/vector/capacity/shrink_to_fit.cc
> b/libstdc++-v3/testsuite/23_containers/vector/capacity/shrink_to_fit.cc
> index d4aa4d89b56..8f81403e7e2 100644
> --- a/libstdc++-v3/testsuite/23_containers/vector/capacity/shrink_to_fit.cc
> +++ b/libstdc++-v3/testsuite/23_containers/vector/capacity/shrink_to_fit.cc
> @@ -30,7 +30,7 @@ void test01()
> v.push_back(1);
> VERIFY( v.size() < v.capacity() );
> v.shrink_to_fit();
> -#ifdef __glibcxx_allocate_at_least
> +#if defined(__glibcxx_allocate_at_least) && __cpp_aligned_new
> unsigned limit = __STDCPP_DEFAULT_NEW_ALIGNMENT__ / sizeof(int);
> #else
> unsigned limit = 0;
> diff --git
> a/libstdc++-v3/testsuite/23_containers/vector/capacity/shrink_to_fit2.cc
> b/libstdc++-v3/testsuite/23_containers/vector/capacity/shrink_to_fit2.cc
> index 9489e043845..edac0de271f 100644
> --- a/libstdc++-v3/testsuite/23_containers/vector/capacity/shrink_to_fit2.cc
> +++ b/libstdc++-v3/testsuite/23_containers/vector/capacity/shrink_to_fit2.cc
> @@ -32,7 +32,7 @@ void test01()
> v.reserve(100);
> VERIFY( v.size() < v.capacity() );
> v.shrink_to_fit();
> -#ifdef __glibcxx_allocate_at_least
> +#if defined(__glibcxx_allocate_at_least) && __cpp_aligned_new
> unsigned limit = __STDCPP_DEFAULT_NEW_ALIGNMENT__ / sizeof(int);
> #else
> unsigned limit = 0;
> @@ -50,7 +50,7 @@ void test02()
> v.reserve(100);
> VERIFY( v.size() < v.capacity() );
> v.shrink_to_fit();
> -#ifdef __glibcxx_allocate_at_least
> +#if defined(__glibcxx_allocate_at_least) && __cpp_aligned_new
> unsigned limit = __STDCPP_DEFAULT_NEW_ALIGNMENT__ / sizeof(int);
> #else
> unsigned limit = 0;
> diff --git
> a/libstdc++-v3/testsuite/23_containers/vector/modifiers/emplace/self_emplace.cc
>
> b/libstdc++-v3/testsuite/23_containers/vector/modifiers/emplace/self_emplace.cc
> index abb416208ea..e6b84d8e8e7 100644
> ---
> a/libstdc++-v3/testsuite/23_containers/vector/modifiers/emplace/self_emplace.cc
> +++
> b/libstdc++-v3/testsuite/23_containers/vector/modifiers/emplace/self_emplace.cc
> @@ -100,7 +100,7 @@ struct A
> void
> test03()
> {
> -#ifdef __glibcxx_allocate_at_least
> +#if defined(__glibcxx_allocate_at_least) && __cpp_aligned_new
> unsigned fit = __STDCPP_DEFAULT_NEW_ALIGNMENT__ / sizeof(A);
> #else
> unsigned fit = 4;
> @@ -118,7 +118,7 @@ test03()
> void
> test04()
> {
> -#ifdef __glibcxx_allocate_at_least
> +#if defined(__glibcxx_allocate_at_least) && __cpp_aligned_new
> unsigned fit = __STDCPP_DEFAULT_NEW_ALIGNMENT__ / sizeof(A);
> #else
> unsigned fit = 4;
> diff --git a/libstdc++-v3/testsuite/25_algorithms/stable_sort/overaligned.cc
> b/libstdc++-v3/testsuite/25_algorithms/stable_sort/overaligned.cc
> index 3c200624617..f57a03a37f9 100644
> --- a/libstdc++-v3/testsuite/25_algorithms/stable_sort/overaligned.cc
> +++ b/libstdc++-v3/testsuite/25_algorithms/stable_sort/overaligned.cc
> @@ -5,7 +5,11 @@
> #include <cstdint>
> #include <testsuite_hooks.h>
>
> +#if __cpp_aligned_new
> struct alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2) Overaligned
> +#else
> +struct alignas(32) Overaligned
> +#endif
It would be simpler to just use 32, or even 64, unconditionally.
> {
> ~Overaligned()
> {
> --
> 2.54.0
>