[libcxx-commits] [libcxx] [libc++] Properly calculate rounded-up size for `{allocate, make}_shared` (PR #190315)

A. Jiang via libcxx-commits libcxx-commits at lists.llvm.org
Fri Apr 3 00:05:11 PDT 2026


https://github.com/frederick-vs-ja created https://github.com/llvm/llvm-project/pull/190315

Previously, the allocated size might be a bit too small for certain cases. This patch makes the size calculated with potentially larger alignment of the whole control block.

Fixes #169765.

>From d8fc10ccf0942632855e565bf867113b2100e85a Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Fri, 3 Apr 2026 15:03:22 +0800
Subject: [PATCH] [libc++] Properly calculate rounded-up size for
 `{allocate,make}_shared`

Previously, the allocated size might be a bit too small for certain
cases. This patch makes the size calculated with potentially larger
alignment of the whole control block.
---
 libcxx/include/__memory/shared_ptr.h                  |  2 +-
 .../allocate_shared.array.unbounded.pass.cpp          | 11 +++++++++++
 .../make_shared.array.unbounded.pass.cpp              | 11 +++++++++++
 3 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/libcxx/include/__memory/shared_ptr.h b/libcxx/include/__memory/shared_ptr.h
index 4fbd0af98463e..4c86eb160ef1a 100644
--- a/libcxx/include/__memory/shared_ptr.h
+++ b/libcxx/include/__memory/shared_ptr.h
@@ -752,7 +752,7 @@ struct __unbounded_array_control_block<_Tp[], _Alloc> : __shared_weak_count {
     // [1]: https://en.wikipedia.org/wiki/Data_structure_alignment#Computing_padding
     size_t __bytes           = __elements == 0 ? sizeof(__unbounded_array_control_block)
                                                : (__elements - 1) * sizeof(_Tp) + sizeof(__unbounded_array_control_block);
-    constexpr size_t __align = alignof(_Tp);
+    constexpr size_t __align = alignof(__unbounded_array_control_block);
     return (__bytes + __align - 1) & ~(__align - 1);
   }
 
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.array.unbounded.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.array.unbounded.pass.cpp
index f3802e32f75bc..ee8c9d5ea596f 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.array.unbounded.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.array.unbounded.pass.cpp
@@ -107,6 +107,17 @@ int main(int, char**) {
         assert(ptr[i][2][1] == 0);
       }
     }
+    {
+      // https://llvm.org/PR169765
+      // Ensure that the allocated size is properly rounded up
+      using Array                = char[][3];
+      std::shared_ptr<Array> ptr = std::allocate_shared<Array>(std::allocator<Array>{}, 3);
+      for (unsigned i = 0; i < 3; ++i) {
+        assert(ptr[i][0] == '\0');
+        assert(ptr[i][1] == '\0');
+        assert(ptr[i][2] == '\0');
+      }
+    }
 
     // Passing an initial value
     {
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.array.unbounded.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.array.unbounded.pass.cpp
index cd6c548010692..56d123a5fc284 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.array.unbounded.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.array.unbounded.pass.cpp
@@ -105,6 +105,17 @@ int main(int, char**) {
         assert(ptr[i][2][1] == 0);
       }
     }
+    {
+      // https://llvm.org/PR169765
+      // Ensure that the allocated size is properly rounded up
+      using Array                = char[][3];
+      std::shared_ptr<Array> ptr = std::make_shared<Array>(3);
+      for (unsigned i = 0; i < 3; ++i) {
+        assert(ptr[i][0] == '\0');
+        assert(ptr[i][1] == '\0');
+        assert(ptr[i][2] == '\0');
+      }
+    }
 
     // Passing an initial value
     {



More information about the libcxx-commits mailing list