[libcxx-commits] [libcxx] [libc++] constexpr is_sufficiently_aligned (PR #146787)

Damien L-G via libcxx-commits libcxx-commits at lists.llvm.org
Thu Jul 3 05:44:14 PDT 2025


https://github.com/dalg24 updated https://github.com/llvm/llvm-project/pull/146787

>From f6e9679c72bffe8f52ed56b8b0759cc1bfdee465 Mon Sep 17 00:00:00 2001
From: Damien L-G <dalg24 at gmail.com>
Date: Wed, 2 Jul 2025 17:14:51 -0400
Subject: [PATCH 1/2] [libc++] constexpr is_sufficiently_aligned

This is indended as support for filing a LWG issue.
The implementation was suggested by Nikolas in https://github.com/llvm/llvm-project/pull/122603/files#r2035285951
---
 libcxx/include/__memory/is_sufficiently_aligned.h        | 4 ++--
 .../memory/ptr.align/is_sufficiently_aligned.pass.cpp    | 9 +++++----
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/libcxx/include/__memory/is_sufficiently_aligned.h b/libcxx/include/__memory/is_sufficiently_aligned.h
index 4280920cabb4b..45a958c628b19 100644
--- a/libcxx/include/__memory/is_sufficiently_aligned.h
+++ b/libcxx/include/__memory/is_sufficiently_aligned.h
@@ -23,8 +23,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 #if _LIBCPP_STD_VER >= 26
 
 template <size_t _Alignment, class _Tp>
-_LIBCPP_HIDE_FROM_ABI bool is_sufficiently_aligned(_Tp* __ptr) {
-  return reinterpret_cast<uintptr_t>(__ptr) % _Alignment == 0;
+_LIBCPP_HIDE_FROM_ABI constexpr bool is_sufficiently_aligned(_Tp* __ptr) {
+  return __builtin_constant_p(__builtin_assume_aligned(__ptr, _Alignment) != nullptr);
 }
 
 #endif // _LIBCPP_STD_VER >= 26
diff --git a/libcxx/test/std/utilities/memory/ptr.align/is_sufficiently_aligned.pass.cpp b/libcxx/test/std/utilities/memory/ptr.align/is_sufficiently_aligned.pass.cpp
index fb40459cfe470..ec05af5143a9c 100644
--- a/libcxx/test/std/utilities/memory/ptr.align/is_sufficiently_aligned.pass.cpp
+++ b/libcxx/test/std/utilities/memory/ptr.align/is_sufficiently_aligned.pass.cpp
@@ -21,7 +21,7 @@
 #include "test_macros.h"
 
 template <typename T>
-void test_is_sufficiently_aligned() {
+constexpr void test_is_sufficiently_aligned() {
   constexpr std::size_t N = alignof(T);
 
   alignas(8 * N) std::remove_cv_t<T> buf[5];
@@ -54,7 +54,7 @@ void test_is_sufficiently_aligned() {
 }
 
 template <typename T>
-void check(T* p) {
+constexpr void check(T* p) {
   ASSERT_SAME_TYPE(bool, decltype(std::is_sufficiently_aligned<alignof(T)>(p)));
   test_is_sufficiently_aligned<T>();
   test_is_sufficiently_aligned<const T>();
@@ -73,7 +73,7 @@ struct alignas(1) X {
 };
 static_assert(sizeof(X) == 2 * alignof(X));
 
-bool tests() {
+constexpr bool test() {
   char c;
   int i;
   long l;
@@ -107,7 +107,8 @@ bool tests() {
 }
 
 int main(int, char**) {
-  tests();
+  test();
+  static_assert(test());
 
   return 0;
 }

>From 35ccbe6e8d796e49c6c5597371b8367d7364c0f5 Mon Sep 17 00:00:00 2001
From: Damien L-G <dalg24 at gmail.com>
Date: Thu, 3 Jul 2025 08:41:37 -0400
Subject: [PATCH 2/2] Use __builtin_is_aligned with Clang and fix GCC
 implemtation

---
 libcxx/include/__memory/is_sufficiently_aligned.h | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/libcxx/include/__memory/is_sufficiently_aligned.h b/libcxx/include/__memory/is_sufficiently_aligned.h
index 45a958c628b19..92276a5cd007e 100644
--- a/libcxx/include/__memory/is_sufficiently_aligned.h
+++ b/libcxx/include/__memory/is_sufficiently_aligned.h
@@ -12,6 +12,7 @@
 
 #include <__config>
 #include <__cstddef/size_t.h>
+#include <__type_traits/is_constant_evaluated.h>
 #include <cstdint>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -24,7 +25,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <size_t _Alignment, class _Tp>
 _LIBCPP_HIDE_FROM_ABI constexpr bool is_sufficiently_aligned(_Tp* __ptr) {
-  return __builtin_constant_p(__builtin_assume_aligned(__ptr, _Alignment) != nullptr);
+#  ifdef _LIBCPP_COMPILER_CLANG_BASED
+  return __builtin_is_aligned(__ptr, _Alignment);
+#  else
+  if constexpr (is_constant_evaluated())
+    return __builtin_constant_p(__builtin_assume_aligned(__ptr, _Alignment) != nullptr);
+  else
+    return reinterpret_cast<uintptr_t>(__ptr) % _Alignment == 0;
+#  endif
 }
 
 #endif // _LIBCPP_STD_VER >= 26



More information about the libcxx-commits mailing list