[libcxx-commits] [libcxx] e65fd77 - [libc++] Assert that the alignment for memory_resource::allocate is a power of two (#219174)

via libcxx-commits libcxx-commits at lists.llvm.org
Fri Sep 4 04:15:48 PDT 2026


Author: Nikolas Klauser
Date: 2026-09-04T13:15:43+02:00
New Revision: e65fd7755ae3d60168b603c405d08381a2637d2f

URL: https://github.com/llvm/llvm-project/commit/e65fd7755ae3d60168b603c405d08381a2637d2f
DIFF: https://github.com/llvm/llvm-project/commit/e65fd7755ae3d60168b603c405d08381a2637d2f.diff

LOG: [libc++] Assert that the alignment for memory_resource::allocate is a power of two (#219174)

`do_allocate` has a precondition that the argument is a power of two. We
can't assert that in general, since users can provide their own
`do_allocate`s. However, we can assert in `allocate` instead, which has
the added bonus that it's going to be inlined and the check can then
most likely be folded away by the compiler.

Added: 
    libcxx/test/libcxx/mem/mem.res/assert.pass.cpp

Modified: 
    libcxx/include/__memory_resource/memory_resource.h

Removed: 
    libcxx/test/libcxx/mem/mem.res/ctor.nullptr.assert.pass.cpp


################################################################################
diff  --git a/libcxx/include/__memory_resource/memory_resource.h b/libcxx/include/__memory_resource/memory_resource.h
index c5726bd2bcdb5..44e2df8e3ec73 100644
--- a/libcxx/include/__memory_resource/memory_resource.h
+++ b/libcxx/include/__memory_resource/memory_resource.h
@@ -9,6 +9,8 @@
 #ifndef _LIBCPP___MEMORY_RESOURCE_MEMORY_RESOURCE_H
 #define _LIBCPP___MEMORY_RESOURCE_MEMORY_RESOURCE_H
 
+#include <__assert>
+#include <__bit/popcount.h>
 #include <__config>
 #include <__cstddef/max_align_t.h>
 #include <__cstddef/size_t.h>
@@ -35,6 +37,7 @@ class _LIBCPP_AVAILABILITY_PMR _LIBCPP_EXPORTED_FROM_ABI memory_resource {
 
   [[nodiscard]] [[using __gnu__: __returns_nonnull__, __alloc_size__(2), __alloc_align__(3)]]
   _LIBCPP_HIDE_FROM_ABI void* allocate(size_t __bytes, size_t __align = __max_align) {
+    _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(std::__popcount(__align) == 1, "The alignment has to be a power of two");
     return do_allocate(__bytes, __align);
   }
 

diff  --git a/libcxx/test/libcxx/mem/mem.res/ctor.nullptr.assert.pass.cpp b/libcxx/test/libcxx/mem/mem.res/assert.pass.cpp
similarity index 57%
rename from libcxx/test/libcxx/mem/mem.res/ctor.nullptr.assert.pass.cpp
rename to libcxx/test/libcxx/mem/mem.res/assert.pass.cpp
index c14eb85323183..c966f9530db8b 100644
--- a/libcxx/test/libcxx/mem/mem.res/ctor.nullptr.assert.pass.cpp
+++ b/libcxx/test/libcxx/mem/mem.res/assert.pass.cpp
@@ -14,15 +14,25 @@
 // UNSUPPORTED: c++03, c++11, c++14
 
 // We're testing nullptr assertions
-// ADDITIONAL_COMPILE_FLAGS: -Wno-nonnull
+// ADDITIONAL_COMPILE_FLAGS: -Wno-nonnull -Wno-non-power-of-two-alignment
 
+#include <cassert>
 #include <memory_resource>
 
 #include "check_assertion.h"
 
+struct my_memory_resource : std::pmr::memory_resource {
+  void* do_allocate(std::size_t, std::size_t) override { assert(false); }
+  void do_deallocate(void*, std::size_t, std::size_t) override { assert(false); }
+  bool do_is_equal(const std::pmr::memory_resource&) const noexcept override { return false; }
+};
+
 int main(int, char**) {
   TEST_LIBCPP_ASSERT_FAILURE(
       std::pmr::polymorphic_allocator<int>(nullptr), "Attempted to pass a nullptr resource to polymorphic_alloator");
 
+  TEST_LIBCPP_ASSERT_FAILURE(my_memory_resource().allocate(0, 0), "The alignment has to be a power of two");
+  TEST_LIBCPP_ASSERT_FAILURE(my_memory_resource().allocate(0, 33), "The alignment has to be a power of two");
+
   return 0;
 }


        


More information about the libcxx-commits mailing list