[libcxx-commits] [libcxx] [libc++] Implement LWG4290: Missing Mandates clauses on is_sufficiently_aligned (PR #229765)
via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Oct 8 08:04:47 PDT 2026
https://github.com/KaroliShp updated https://github.com/llvm/llvm-project/pull/229765
>From accffea988f6fc4f9a23e585f89225d1738ddd17 Mon Sep 17 00:00:00 2001
From: Karolis <karolis.spukas at gmail.com>
Date: Wed, 7 Oct 2026 13:17:10 +0100
Subject: [PATCH 1/3] [libc++] Implement LWG4290: Missing Mandates clauses on
is_sufficiently_aligned
---
libcxx/docs/Status/Cxx26Issues.csv | 2 +-
.../__memory/is_sufficiently_aligned.h | 3 ++
.../is_sufficiently_aligned.power2.verify.cpp | 28 +++++++++++++++++++
3 files changed, 32 insertions(+), 1 deletion(-)
create mode 100644 libcxx/test/libcxx/utilities/memory/ptr.align/is_sufficiently_aligned.power2.verify.cpp
diff --git a/libcxx/docs/Status/Cxx26Issues.csv b/libcxx/docs/Status/Cxx26Issues.csv
index 7cb257a49c30f..9f2a8edbde8c9 100644
--- a/libcxx/docs/Status/Cxx26Issues.csv
+++ b/libcxx/docs/Status/Cxx26Issues.csv
@@ -278,7 +278,7 @@
"`LWG4151 <https://wg21.link/LWG4151>`__","Precondition of ``inplace_vector::swap``","2026-03 (Croydon)","","","`#189820 <https://github.com/llvm/llvm-project/issues/189820>`__",""
"`LWG4223 <https://wg21.link/LWG4223>`__","Deduction guides for maps are mishandling tuples and references","2026-03 (Croydon)","","","`#189821 <https://github.com/llvm/llvm-project/issues/189821>`__",""
"`LWG4259 <https://wg21.link/LWG4259>`__","P1148R0 changed the return values of searching functions of ``std::basic_string`` on some platforms","2026-03 (Croydon)","","","`#189822 <https://github.com/llvm/llvm-project/issues/189822>`__",""
-"`LWG4290 <https://wg21.link/LWG4290>`__","Missing *Mandates* clauses on ``is_sufficiently_aligned``","2026-03 (Croydon)","","","`#189823 <https://github.com/llvm/llvm-project/issues/189823>`__",""
+"`LWG4290 <https://wg21.link/LWG4290>`__","Missing *Mandates* clauses on ``is_sufficiently_aligned``","2026-03 (Croydon)","|Complete|","24","`#189823 <https://github.com/llvm/llvm-project/issues/189823>`__",""
"`LWG4314 <https://wg21.link/LWG4314>`__","Missing move in ``mdspan`` layout ``mapping::operator()``","2026-03 (Croydon)","","","`#189824 <https://github.com/llvm/llvm-project/issues/189824>`__",""
"`LWG4324 <https://wg21.link/LWG4324>`__","``unique_ptr<void>::operator*`` is not SFINAE-friendly","2026-03 (Croydon)","|Complete|","23","`#189825 <https://github.com/llvm/llvm-project/issues/189825>`__",""
"`LWG4325 <https://wg21.link/LWG4325>`__","``std::indirect``'s ``operator==`` still does not support incomplete types","2026-03 (Croydon)","","","`#189826 <https://github.com/llvm/llvm-project/issues/189826>`__",""
diff --git a/libcxx/include/__memory/is_sufficiently_aligned.h b/libcxx/include/__memory/is_sufficiently_aligned.h
index b8725880028db..923c502008835 100644
--- a/libcxx/include/__memory/is_sufficiently_aligned.h
+++ b/libcxx/include/__memory/is_sufficiently_aligned.h
@@ -22,6 +22,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <size_t _Alignment, class _Tp>
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool __is_sufficiently_aligned(_Tp* __ptr) {
+ static_assert(_Alignment != 0 && (_Alignment & (_Alignment - 1)) == 0,
+ "std::is_sufficiently_aligned<Alignment>(p) requires Alignment to be a power of two");
+
return reinterpret_cast<uintptr_t>(__ptr) % _Alignment == 0;
}
diff --git a/libcxx/test/libcxx/utilities/memory/ptr.align/is_sufficiently_aligned.power2.verify.cpp b/libcxx/test/libcxx/utilities/memory/ptr.align/is_sufficiently_aligned.power2.verify.cpp
new file mode 100644
index 0000000000000..76c015052babf
--- /dev/null
+++ b/libcxx/test/libcxx/utilities/memory/ptr.align/is_sufficiently_aligned.power2.verify.cpp
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+// #include <memory>
+
+// template<size_t Alignment, class T>
+// bool is_sufficiently_aligned(T* ptr);
+
+#include <memory>
+
+void f() {
+ int* p = nullptr;
+ (void)std::is_sufficiently_aligned<0>(
+ p); // expected-error@*:* {{std::is_sufficiently_aligned<Alignment>(p) requires Alignment to be a power of two}}
+ (void)std::is_sufficiently_aligned<3>(
+ p); // expected-error@*:* {{std::is_sufficiently_aligned<Alignment>(p) requires Alignment to be a power of two}}
+ (void)std::is_sufficiently_aligned<5>(
+ p); // expected-error@*:* {{std::is_sufficiently_aligned<Alignment>(p) requires Alignment to be a power of two}}
+ (void)std::is_sufficiently_aligned<33>(
+ p); // expected-error@*:* {{std::is_sufficiently_aligned<Alignment>(p) requires Alignment to be a power of two}}
+}
>From 8a3c5cbc844a9885232e7040572696f242946043 Mon Sep 17 00:00:00 2001
From: Karolis <karolis.spukas at gmail.com>
Date: Thu, 8 Oct 2026 09:57:21 +0100
Subject: [PATCH 2/3] Address review comments: shorten static_assert message
---
libcxx/include/__memory/is_sufficiently_aligned.h | 3 +--
.../is_sufficiently_aligned.power2.verify.cpp | 12 ++++--------
2 files changed, 5 insertions(+), 10 deletions(-)
diff --git a/libcxx/include/__memory/is_sufficiently_aligned.h b/libcxx/include/__memory/is_sufficiently_aligned.h
index 923c502008835..61b77ae7b027f 100644
--- a/libcxx/include/__memory/is_sufficiently_aligned.h
+++ b/libcxx/include/__memory/is_sufficiently_aligned.h
@@ -22,8 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <size_t _Alignment, class _Tp>
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool __is_sufficiently_aligned(_Tp* __ptr) {
- static_assert(_Alignment != 0 && (_Alignment & (_Alignment - 1)) == 0,
- "std::is_sufficiently_aligned<Alignment>(p) requires Alignment to be a power of two");
+ static_assert(_Alignment != 0 && (_Alignment & (_Alignment - 1)) == 0, "_Alignment should be a power of two.");
return reinterpret_cast<uintptr_t>(__ptr) % _Alignment == 0;
}
diff --git a/libcxx/test/libcxx/utilities/memory/ptr.align/is_sufficiently_aligned.power2.verify.cpp b/libcxx/test/libcxx/utilities/memory/ptr.align/is_sufficiently_aligned.power2.verify.cpp
index 76c015052babf..54bbde0500811 100644
--- a/libcxx/test/libcxx/utilities/memory/ptr.align/is_sufficiently_aligned.power2.verify.cpp
+++ b/libcxx/test/libcxx/utilities/memory/ptr.align/is_sufficiently_aligned.power2.verify.cpp
@@ -17,12 +17,8 @@
void f() {
int* p = nullptr;
- (void)std::is_sufficiently_aligned<0>(
- p); // expected-error@*:* {{std::is_sufficiently_aligned<Alignment>(p) requires Alignment to be a power of two}}
- (void)std::is_sufficiently_aligned<3>(
- p); // expected-error@*:* {{std::is_sufficiently_aligned<Alignment>(p) requires Alignment to be a power of two}}
- (void)std::is_sufficiently_aligned<5>(
- p); // expected-error@*:* {{std::is_sufficiently_aligned<Alignment>(p) requires Alignment to be a power of two}}
- (void)std::is_sufficiently_aligned<33>(
- p); // expected-error@*:* {{std::is_sufficiently_aligned<Alignment>(p) requires Alignment to be a power of two}}
+ (void)std::is_sufficiently_aligned<0>(p); // expected-error@*:* {{_Alignment should be a power of two.}}
+ (void)std::is_sufficiently_aligned<3>(p); // expected-error@*:* {{_Alignment should be a power of two.}}
+ (void)std::is_sufficiently_aligned<5>(p); // expected-error@*:* {{_Alignment should be a power of two.}}
+ (void)std::is_sufficiently_aligned<33>(p); // expected-error@*:* {{_Alignment should be a power of two.}}
}
>From a2a6cff34927a7c4a79eb5108c15a30f932d9520 Mon Sep 17 00:00:00 2001
From: Karolis <karolis.spukas at gmail.com>
Date: Thu, 8 Oct 2026 16:04:31 +0100
Subject: [PATCH 3/3] Address review comments: restrict to C++20 and use std
has_single_bit
---
libcxx/include/__memory/is_sufficiently_aligned.h | 11 ++++++++---
.../is_sufficiently_aligned.power2.verify.cpp | 8 ++++----
2 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/libcxx/include/__memory/is_sufficiently_aligned.h b/libcxx/include/__memory/is_sufficiently_aligned.h
index 61b77ae7b027f..587710d7e3526 100644
--- a/libcxx/include/__memory/is_sufficiently_aligned.h
+++ b/libcxx/include/__memory/is_sufficiently_aligned.h
@@ -10,6 +10,7 @@
#ifndef _LIBCPP___MEMORY_IS_SUFFICIENTLY_ALIGNED_H
#define _LIBCPP___MEMORY_IS_SUFFICIENTLY_ALIGNED_H
+#include <__bit/has_single_bit.h>
#include <__config>
#include <__cstddef/size_t.h>
#include <cstdint>
@@ -18,24 +19,28 @@
# pragma GCC system_header
#endif
+#if _LIBCPP_STD_VER >= 20
+
_LIBCPP_BEGIN_NAMESPACE_STD
template <size_t _Alignment, class _Tp>
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI bool __is_sufficiently_aligned(_Tp* __ptr) {
- static_assert(_Alignment != 0 && (_Alignment & (_Alignment - 1)) == 0, "_Alignment should be a power of two.");
+ static_assert(std::has_single_bit(_Alignment), "alignment must be a power of two.");
return reinterpret_cast<uintptr_t>(__ptr) % _Alignment == 0;
}
-#if _LIBCPP_STD_VER >= 26
+# if _LIBCPP_STD_VER >= 26
template <size_t _Alignment, class _Tp>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool is_sufficiently_aligned(_Tp* __ptr) {
return std::__is_sufficiently_aligned<_Alignment>(__ptr);
}
-#endif // _LIBCPP_STD_VER >= 26
+# endif // _LIBCPP_STD_VER >= 26
_LIBCPP_END_NAMESPACE_STD
+#endif // _LIBCPP_STD_VER >= 20
+
#endif // _LIBCPP___MEMORY_IS_SUFFICIENTLY_ALIGNED_H
diff --git a/libcxx/test/libcxx/utilities/memory/ptr.align/is_sufficiently_aligned.power2.verify.cpp b/libcxx/test/libcxx/utilities/memory/ptr.align/is_sufficiently_aligned.power2.verify.cpp
index 54bbde0500811..cde7aa38deb74 100644
--- a/libcxx/test/libcxx/utilities/memory/ptr.align/is_sufficiently_aligned.power2.verify.cpp
+++ b/libcxx/test/libcxx/utilities/memory/ptr.align/is_sufficiently_aligned.power2.verify.cpp
@@ -17,8 +17,8 @@
void f() {
int* p = nullptr;
- (void)std::is_sufficiently_aligned<0>(p); // expected-error@*:* {{_Alignment should be a power of two.}}
- (void)std::is_sufficiently_aligned<3>(p); // expected-error@*:* {{_Alignment should be a power of two.}}
- (void)std::is_sufficiently_aligned<5>(p); // expected-error@*:* {{_Alignment should be a power of two.}}
- (void)std::is_sufficiently_aligned<33>(p); // expected-error@*:* {{_Alignment should be a power of two.}}
+ (void)std::is_sufficiently_aligned<0>(p); // expected-error@*:* {{alignment must be a power of two.}}
+ (void)std::is_sufficiently_aligned<3>(p); // expected-error@*:* {{alignment must be a power of two.}}
+ (void)std::is_sufficiently_aligned<5>(p); // expected-error@*:* {{alignment must be a power of two.}}
+ (void)std::is_sufficiently_aligned<33>(p); // expected-error@*:* {{alignment must be a power of two.}}
}
More information about the libcxx-commits
mailing list