On Thu, 17 Jul 2025 at 10:05, Luc Grosheintz <luc.groshei...@gmail.com> wrote:
>
>
>
> On 7/8/25 16:56, Tomasz Kaminski wrote:
> > On Thu, Jul 3, 2025 at 12:36 PM Luc Grosheintz <luc.groshei...@gmail.com>
> > wrote:
> >
> >> This commit implements and tests the function is_sufficiently_aligned
> >> from P2897R7.
> >>
> >> libstdc++-v3/ChangeLog:
> >>
> >>          * include/bits/align.h (is_sufficiently_aligned): New function.
> >>          * include/bits/version.def (is_sufficiently_aligned): Add.
> >>          * include/bits/version.h: Regenerate.
> >>          * include/std/memory: Add __glibcxx_want_is_sufficiently_aligned.
> >>          * src/c++23/std.cc.in (is_sufficiently_aligned): Add.
> >>          * testsuite/20_util/is_sufficiently_aligned/1.cc: New test.
> >>          * testsuite/20_util/is_sufficiently_aligned/2.cc: New test.
> >> ---
> >>
> > Only one small suggestion on placement of the tests. Otherwise it looks
> > good.
> >
> >>   libstdc++-v3/include/bits/align.h             | 16 ++++++++++
> >>   libstdc++-v3/include/bits/version.def         |  8 +++++
> >>   libstdc++-v3/include/bits/version.h           | 10 ++++++
> >>   libstdc++-v3/include/std/memory               |  1 +
> >>   libstdc++-v3/src/c++23/std.cc.in              |  1 +
> >>   .../20_util/is_sufficiently_aligned/1.cc      | 31 +++++++++++++++++++
> >>   .../20_util/is_sufficiently_aligned/2.cc      |  7 +++++
> >>   7 files changed, 74 insertions(+)
> >>   create mode 100644
> >> libstdc++-v3/testsuite/20_util/is_sufficiently_aligned/1.cc
> >>   create mode 100644
> >> libstdc++-v3/testsuite/20_util/is_sufficiently_aligned/2.cc
> >>
> >> diff --git a/libstdc++-v3/include/bits/align.h
> >> b/libstdc++-v3/include/bits/align.h
> >> index 2b40c37e033..fbbe9cb1f9c 100644
> >> --- a/libstdc++-v3/include/bits/align.h
> >> +++ b/libstdc++-v3/include/bits/align.h
> >> @@ -102,6 +102,22 @@ align(size_t __align, size_t __size, void*& __ptr,
> >> size_t& __space) noexcept
> >>       }
> >>   #endif // __glibcxx_assume_aligned
> >>
> >> +#ifdef __glibcxx_is_sufficiently_aligned // C++ >= 26
> >> +  /** @brief Is @a __ptr aligned to an _Align byte boundary?
> >> +   *
> >> +   *  @tparam _Align An alignment value
> >> +   *  @tparam _Tp    An object type
> >> +   *
> >> +   *  C++26 20.2.5 [ptr.align]
> >> +   *
> >> +   *  @ingroup memory
> >> +   */
> >> +  template<size_t _Align, class _Tp>
> >> +    bool
> >> +    is_sufficiently_aligned(_Tp* __ptr)
> >> +    { return reinterpret_cast<__UINTPTR_TYPE__>(__ptr) % _Align == 0; }
> >> +#endif // __glibcxx_is_sufficiently_aligned
> >> +
> >>   _GLIBCXX_END_NAMESPACE_VERSION
> >>   } // namespace
> >>
> >> diff --git a/libstdc++-v3/include/bits/version.def
> >> b/libstdc++-v3/include/bits/version.def
> >> index f4ba501c403..a2695e67716 100644
> >> --- a/libstdc++-v3/include/bits/version.def
> >> +++ b/libstdc++-v3/include/bits/version.def
> >> @@ -732,6 +732,14 @@ ftms = {
> >>     };
> >>   };
> >>
> >> +ftms = {
> >> +  name = is_sufficiently_aligned;
> >> +  values = {
> >> +    v = 202411;
> >> +    cxxmin = 26;
> >> +  };
> >> +};
> >> +
> >>   ftms = {
> >>     name = atomic_flag_test;
> >>     values = {
> >> diff --git a/libstdc++-v3/include/bits/version.h
> >> b/libstdc++-v3/include/bits/version.h
> >> index dc8ac07be16..1b17a965239 100644
> >> --- a/libstdc++-v3/include/bits/version.h
> >> +++ b/libstdc++-v3/include/bits/version.h
> >> @@ -815,6 +815,16 @@
> >>   #endif /* !defined(__cpp_lib_assume_aligned) &&
> >> defined(__glibcxx_want_assume_aligned) */
> >>   #undef __glibcxx_want_assume_aligned
> >>
> >> +#if !defined(__cpp_lib_is_sufficiently_aligned)
> >> +# if (__cplusplus >  202302L)
> >> +#  define __glibcxx_is_sufficiently_aligned 202411L
> >> +#  if defined(__glibcxx_want_all) ||
> >> defined(__glibcxx_want_is_sufficiently_aligned)
> >> +#   define __cpp_lib_is_sufficiently_aligned 202411L
> >> +#  endif
> >> +# endif
> >> +#endif /* !defined(__cpp_lib_is_sufficiently_aligned) &&
> >> defined(__glibcxx_want_is_sufficiently_aligned) */
> >> +#undef __glibcxx_want_is_sufficiently_aligned
> >> +
> >>   #if !defined(__cpp_lib_atomic_flag_test)
> >>   # if (__cplusplus >= 202002L)
> >>   #  define __glibcxx_atomic_flag_test 201907L
> >> diff --git a/libstdc++-v3/include/std/memory
> >> b/libstdc++-v3/include/std/memory
> >> index 1da03b3ea6a..ff342ff35f3 100644
> >> --- a/libstdc++-v3/include/std/memory
> >> +++ b/libstdc++-v3/include/std/memory
> >> @@ -110,6 +110,7 @@
> >>   #define __glibcxx_want_constexpr_memory
> >>   #define __glibcxx_want_enable_shared_from_this
> >>   #define __glibcxx_want_indirect
> >> +#define __glibcxx_want_is_sufficiently_aligned
> >>   #define __glibcxx_want_make_unique
> >>   #define __glibcxx_want_out_ptr
> >>   #define __glibcxx_want_parallel_algorithm
> >> diff --git a/libstdc++-v3/src/c++23/std.cc.in b/libstdc++-v3/src/c++23/
> >> std.cc.in
> >> index e692caaa5f9..6f4214ed3a7 100644
> >> --- a/libstdc++-v3/src/c++23/std.cc.in
> >> +++ b/libstdc++-v3/src/c++23/std.cc.in
> >> @@ -1864,6 +1864,7 @@ export namespace std
> >>     using std::allocator_arg_t;
> >>     using std::allocator_traits;
> >>     using std::assume_aligned;
> >> +  using std::is_sufficiently_aligned;
> >>     using std::make_obj_using_allocator;
> >>     using std::pointer_traits;
> >>     using std::to_address;
> >> diff --git a/libstdc++-v3/testsuite/20_util/is_sufficiently_aligned/1.cc
> >> b/libstdc++-v3/testsuite/20_util/is_sufficiently_aligned/1.cc
> >> new file mode 100644
> >> index 00000000000..4c2738b57db
> >> --- /dev/null
> >> +++ b/libstdc++-v3/testsuite/20_util/is_sufficiently_aligned/1.cc
> >> @@ -0,0 +1,31 @@
> >> +// { dg-do run { target c++26 } }
> >> +
> >> +#include <memory>
> >> +#include <array>
> >> +#include <testsuite_hooks.h>
> >> +
> >> +void
> >> +test01()
> >> +{
> >> +  constexpr size_t N = 4;
> >> +  constexpr size_t M = 2*N + 1;
> >> +  alignas(N) std::array<char, M> buffer{};
> >> +
> >> +  auto* ptr = buffer.data();
> >> +  VERIFY(std::is_sufficiently_aligned<1>(ptr+0));
> >> +  VERIFY(std::is_sufficiently_aligned<1>(ptr+1));
> >> +
> >> +  VERIFY(std::is_sufficiently_aligned<2>(ptr+0));
> >> +  VERIFY(!std::is_sufficiently_aligned<2>(ptr+1));
> >> +  VERIFY(std::is_sufficiently_aligned<2>(ptr+2));
> >> +
> >> +  for (size_t i = 0; i < M; ++i)
> >> +    VERIFY(std::is_sufficiently_aligned<N>(ptr + i) == (i % N == 0));
> >> +}
> >> +
> >> +int
> >> +main()
> >> +{
> >> +  test01();
> >> +  return 0;
> >> +}
> >> diff --git a/libstdc++-v3/testsuite/20_util/is_sufficiently_aligned/2.cc
> >> b/libstdc++-v3/testsuite/20_util/is_sufficiently_aligned/2.cc
> >> new file mode 100644
> >> index 00000000000..8e0f4c07661
> >> --- /dev/null
> >> +++ b/libstdc++-v3/testsuite/20_util/is_sufficiently_aligned/2.cc
> >> @@ -0,0 +1,7 @@
> >> +// { dg-do compile { target c++26 } }
> >> +
> >> +#include <memory>
> >> +
> >> +#ifndef __cpp_lib_is_sufficiently_aligned
> >> +#error "Missing FTM"
> >> +#endif
> >>
> > I would integrate that into 1.cc file directly. I do not think we need a
> > separate test.
>
> Now I know they're called version.cc it's easier to find others. There's
>
>    testsuite/20_util/headers/memory/version.cc
>
> which checks:
>
>    __cpp_lib_allocator_traits_is_always_equal
>    __cpp_lib_addressof_constexpr
>
> That feels like the place to also put this one.

Yes, that makes sense.

> It's use of dejagnu is
> neat too:
>
> // { dg-do preprocess { target c++17 } }

The 'preprocess' does what you'd expect, it stops after preprocessing
(so doesn't bother doing any of compiling and assembling and linking
and running):
https://gcc.gnu.org/onlinedocs/gccint/Directives.html#Specify-how-to-build-the-test
By default this test will only be tested with -std=gnu++17 but people
who run the testsuite with additional/different -std options can test
it for -std=c++26:
https://gcc.gnu.org/onlinedocs/libstdc++/manual/test.html#test.run.permutations

If we really want to be sure the new macro is *always* tested by
everybody running the tests, it needs to be a separate file with {
target c++26 } so that the testsuite chooses -std=gnu++26 for it. So
that's an argument against checking the new macro in the existing
headers/memory/version.cc file. I don't feel strongly about it though,
because I test everything with every -std option several times a day,
and as long as *somebody* is doing that, we'll know it works.

And one day in the future -std=gnu++26 will be the default for all
tests anyway (but that's years away).

> // { dg-add-options no_pch }

This prevents the test harness from adding an implicit -include
bits/stdc++.h which includes every libstdc++ header at the very start
of the file. If the test just wants to check that the macro is defined
by <memory> then including every other header first would not test
what you want to test!
The definition of no_pch is in testsuite/lib/dg-options.exp


>
> Now I'm tempted to adjust mdspan/version.cc accordingly.
>
> >
> >> --
> >> 2.49.0
> >>
> >>
> >
>

Reply via email to