[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 01:57:36 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/2] [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 7cb257a49c30f0..9f2a8edbde8c9b 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 b8725880028db1..923c502008835b 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 00000000000000..76c015052babfe
--- /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/2] 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 923c502008835b..61b77ae7b027f9 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 76c015052babfe..54bbde05008114 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.}}
 }



More information about the libcxx-commits mailing list