Commit c108cd03 by Derek Mauro Committed by Copybara-Service

InlinedVector: Disable CFI checking on GetInlinedData()

GetInlinedDataUninitialized() is removed. Just use GetInlinedData() in
all cases instead. GetInlinedData() is sometimes used to return
uninitialized memory.  In these cases it is immediately constructed.

This is a followup to 511ad649. See also:
https://clang.llvm.org/docs/ControlFlowIntegrity.html#bad-cast-checking.

PiperOrigin-RevId: 551205766
Change-Id: I4ddb45e29a723ccf6fc7dc203e762f4ad559fc83
parent 511ad649
...@@ -1626,6 +1626,12 @@ TEST(DynamicVec, CreateNonEmptyDynamicVec) { ...@@ -1626,6 +1626,12 @@ TEST(DynamicVec, CreateNonEmptyDynamicVec) {
EXPECT_EQ(v.size(), 1u); EXPECT_EQ(v.size(), 1u);
} }
TEST(DynamicVec, EmplaceBack) {
DynamicVec v;
v.emplace_back(Dynamic{});
EXPECT_EQ(v.size(), 1u);
}
TEST(AllocatorSupportTest, Constructors) { TEST(AllocatorSupportTest, Constructors) {
using MyAlloc = CountingAllocator<int>; using MyAlloc = CountingAllocator<int>;
using AllocVec = absl::InlinedVector<int, 4, MyAlloc>; using AllocVec = absl::InlinedVector<int, 4, MyAlloc>;
......
...@@ -390,25 +390,20 @@ class Storage { ...@@ -390,25 +390,20 @@ class Storage {
return data_.allocated.allocated_data; return data_.allocated.allocated_data;
} }
Pointer<A> GetInlinedData() { // ABSL_ATTRIBUTE_NO_SANITIZE_CFI is used because the memory pointed to may be
return reinterpret_cast<Pointer<A>>(data_.inlined.inlined_data); // uninitialized, a common pattern in allocate()+construct() APIs.
}
ConstPointer<A> GetInlinedData() const {
return reinterpret_cast<ConstPointer<A>>(data_.inlined.inlined_data);
}
// Like GetInlinedData(), but for data that has not been constructed yet. The
// only difference is ABSL_ATTRIBUTE_NO_SANITIZE_CFI, which is necessary
// because the object is uninitialized.
// https://clang.llvm.org/docs/ControlFlowIntegrity.html#bad-cast-checking // https://clang.llvm.org/docs/ControlFlowIntegrity.html#bad-cast-checking
// NOTE: When this was written, LLVM documentation did not explicitly // NOTE: When this was written, LLVM documentation did not explicitly
// mention that casting `char*` and using `reinterpret_cast` qualifies // mention that casting `char*` and using `reinterpret_cast` qualifies
// as a bad cast. // as a bad cast.
ABSL_ATTRIBUTE_NO_SANITIZE_CFI Pointer<A> GetInlinedDataUninitialized() { ABSL_ATTRIBUTE_NO_SANITIZE_CFI Pointer<A> GetInlinedData() {
return reinterpret_cast<Pointer<A>>(data_.inlined.inlined_data); return reinterpret_cast<Pointer<A>>(data_.inlined.inlined_data);
} }
ConstPointer<A> GetInlinedData() const {
return reinterpret_cast<ConstPointer<A>>(data_.inlined.inlined_data);
}
SizeType<A> GetAllocatedCapacity() const { SizeType<A> GetAllocatedCapacity() const {
return data_.allocated.allocated_capacity; return data_.allocated.allocated_capacity;
} }
...@@ -637,7 +632,7 @@ auto Storage<T, N, A>::Initialize(ValueAdapter values, SizeType<A> new_size) ...@@ -637,7 +632,7 @@ auto Storage<T, N, A>::Initialize(ValueAdapter values, SizeType<A> new_size)
SetAllocation(allocation); SetAllocation(allocation);
SetIsAllocated(); SetIsAllocated();
} else { } else {
construct_data = GetInlinedDataUninitialized(); construct_data = GetInlinedData();
} }
ConstructElements<A>(GetAllocator(), construct_data, values, new_size); ConstructElements<A>(GetAllocator(), construct_data, values, new_size);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment