[PATCH] D51317: Keep BumpPtrAllocator::Allocate(0) from returning nullptr
Brent Royal-Gordon via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 27 12:12:44 PDT 2018
brentdax created this revision.
brentdax added reviewers: hans, jordan_rose.
Herald added a subscriber: llvm-commits.
If a newly-allocated BumpPtrAllocator was asked for a zero-byte allocation, it would return nullptr in violation of its LLVM_ATTRIBUTE_RETURNS_NONNULL attribute. This change instead makes it return a valid but read-only address.
Repository:
rL LLVM
https://reviews.llvm.org/D51317
Files:
include/llvm/Support/Allocator.h
unittests/Support/AllocatorTest.cpp
Index: unittests/Support/AllocatorTest.cpp
===================================================================
--- unittests/Support/AllocatorTest.cpp
+++ unittests/Support/AllocatorTest.cpp
@@ -185,4 +185,19 @@
EXPECT_GT(MockSlabAllocator::GetLastSlabSize(), 4096u);
}
+// Test that Allocate() keeps its promise not to return a nullptr, even if
+// the BumpPtrAllocator performs a size-zero allocation when brand new.
+//
+// Optimizations disabled so we actually compare the pointer to nullptr,
+// instead of assuming the attribute is accurate.
+#pragma clang optimize off
+TEST(AllocatorTest, TestNeverNull) {
+ BumpPtrAllocator Alloc;
+
+ void *P = Alloc.Allocate(0, 1);
+
+ EXPECT_NE(P, nullptr);
+}
+#pragma clang optimize on
+
} // anonymous namespace
Index: include/llvm/Support/Allocator.h
===================================================================
--- include/llvm/Support/Allocator.h
+++ include/llvm/Support/Allocator.h
@@ -159,7 +159,7 @@
CustomSizedSlabs(std::move(Old.CustomSizedSlabs)),
BytesAllocated(Old.BytesAllocated), RedZoneSize(Old.RedZoneSize),
Allocator(std::move(Old.Allocator)) {
- Old.CurPtr = Old.End = nullptr;
+ Old.CurPtr = Old.End = const_cast<char *>(EmptySlabPtr);
Old.BytesAllocated = 0;
Old.Slabs.clear();
Old.CustomSizedSlabs.clear();
@@ -182,7 +182,7 @@
CustomSizedSlabs = std::move(RHS.CustomSizedSlabs);
Allocator = std::move(RHS.Allocator);
- RHS.CurPtr = RHS.End = nullptr;
+ RHS.CurPtr = RHS.End = const_cast<char *>(EmptySlabPtr);
RHS.BytesAllocated = 0;
RHS.Slabs.clear();
RHS.CustomSizedSlabs.clear();
@@ -304,13 +304,17 @@
}
private:
+ /// Initial value for CurPtr and End. This should be a valid address
+ /// so we never return nullptr.
+ static const char EmptySlabPtr[];
+
/// The current pointer into the current slab.
///
/// This points to the next free byte in the slab.
- char *CurPtr = nullptr;
+ char *CurPtr = const_cast<char *>(EmptySlabPtr);
/// The end of the current slab.
- char *End = nullptr;
+ char *End = const_cast<char *>(EmptySlabPtr);
/// The slabs allocated so far.
SmallVector<void *, 4> Slabs;
@@ -375,6 +379,9 @@
template <typename T> friend class SpecificBumpPtrAllocator;
};
+template <typename AllocatorT, size_t SlabSize, size_t SizeThreshold>
+const char BumpPtrAllocatorImpl<AllocatorT, SlabSize, SizeThreshold>::EmptySlabPtr[1] = {0};
+
/// The standard BumpPtrAllocator which just uses the default template
/// parameters.
typedef BumpPtrAllocatorImpl<> BumpPtrAllocator;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D51317.162723.patch
Type: text/x-patch
Size: 2603 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180827/c22b7da9/attachment.bin>
More information about the llvm-commits
mailing list