[libc-commits] [libc] e237e37 - [libc] Fix riscv32 Block assertion failure on #117815

Daniel Thornburgh via libc-commits libc-commits at lists.llvm.org
Fri Jan 17 12:27:50 PST 2025


Author: Daniel Thornburgh
Date: 2025-01-17T12:27:43-08:00
New Revision: e237e37c62804b5caa7ca5501d7372d7b01167ad

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

LOG: [libc] Fix riscv32 Block assertion failure on #117815

Added: 
    

Modified: 
    libc/src/__support/block.h

Removed: 
    


################################################################################
diff  --git a/libc/src/__support/block.h b/libc/src/__support/block.h
index 50a745326eac36..a58c38bbb7acb2 100644
--- a/libc/src/__support/block.h
+++ b/libc/src/__support/block.h
@@ -227,15 +227,17 @@ class Block {
     *new (&next()->prev_) size_t = outer_size();
   }
 
-  /// Marks this block as the last one in the chain. Makes next() return
-  /// nullptr.
-  LIBC_INLINE void mark_last() { next_ |= LAST_MASK; }
-
-  LIBC_INLINE Block(size_t outer_size) : next_(outer_size) {
-    LIBC_ASSERT(outer_size % alignof(max_align_t) == 0 &&
-                "block sizes must be aligned");
+  LIBC_INLINE Block(size_t outer_size, bool is_last) : next_(outer_size) {
+    // Last blocks are not usable, so they need not have sizes aligned to
+    // max_align_t. Their lower bits must still be free, so they must be aligned
+    // to Block.
+    LIBC_ASSERT(
+        outer_size % (is_last ? alignof(Block) : alignof(max_align_t)) == 0 &&
+        "block sizes must be aligned");
     LIBC_ASSERT(is_usable_space_aligned(alignof(max_align_t)) &&
                 "usable space must be aligned to a multiple of max_align_t");
+    if (is_last)
+      next_ |= LAST_MASK;
   }
 
   LIBC_INLINE bool is_usable_space_aligned(size_t alignment) const {
@@ -325,7 +327,13 @@ class Block {
     LIBC_ASSERT(reinterpret_cast<uintptr_t>(bytes.data()) % alignof(Block) ==
                     0 &&
                 "block start must be suitably aligned");
-    return ::new (bytes.data()) Block(bytes.size());
+    return ::new (bytes.data()) Block(bytes.size(), /*is_last=*/false);
+  }
+
+  LIBC_INLINE static void make_last_block(cpp::byte *start) {
+    LIBC_ASSERT(reinterpret_cast<uintptr_t>(start) % alignof(Block) == 0 &&
+                "block start must be suitably aligned");
+    ::new (start) Block(sizeof(Block), /*is_last=*/true);
   }
 
   /// Offset from this block to the previous block. 0 if this is the first
@@ -353,7 +361,7 @@ class Block {
   static constexpr size_t PREV_FIELD_SIZE = sizeof(prev_);
 };
 
-static_assert(alignof(max_align_t) >= 4,
+static_assert(alignof(Block) >= 4,
               "at least 2 bits must be available in block sizes for flags");
 
 LIBC_INLINE
@@ -380,9 +388,8 @@ optional<Block *> Block::init(ByteSpan region) {
   auto *last_start_ptr = reinterpret_cast<cpp::byte *>(last_start);
   Block *block =
       as_block({reinterpret_cast<cpp::byte *>(block_start), last_start_ptr});
-  Block *last = as_block({last_start_ptr, sizeof(Block)});
+  make_last_block(last_start_ptr);
   block->mark_free();
-  last->mark_last();
   return block;
 }
 


        


More information about the libc-commits mailing list