[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