From c108cd0382a3659eaf2981b22392b4d5fbc122db Mon Sep 17 00:00:00 2001 From: Derek Mauro Date: Wed, 26 Jul 2023 07:57:53 -0700 Subject: 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 511ad64. See also: https://clang.llvm.org/docs/ControlFlowIntegrity.html#bad-cast-checking. PiperOrigin-RevId: 551205766 Change-Id: I4ddb45e29a723ccf6fc7dc203e762f4ad559fc83 --- absl/container/inlined_vector_test.cc | 6 ++++++ absl/container/internal/inlined_vector.h | 21 ++++++++------------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/absl/container/inlined_vector_test.cc b/absl/container/inlined_vector_test.cc index 07304518..5acad650 100644 --- a/absl/container/inlined_vector_test.cc +++ b/absl/container/inlined_vector_test.cc @@ -1626,6 +1626,12 @@ TEST(DynamicVec, CreateNonEmptyDynamicVec) { EXPECT_EQ(v.size(), 1u); } +TEST(DynamicVec, EmplaceBack) { + DynamicVec v; + v.emplace_back(Dynamic{}); + EXPECT_EQ(v.size(), 1u); +} + TEST(AllocatorSupportTest, Constructors) { using MyAlloc = CountingAllocator; using AllocVec = absl::InlinedVector; diff --git a/absl/container/internal/inlined_vector.h b/absl/container/internal/inlined_vector.h index 639bf145..cdfd868e 100644 --- a/absl/container/internal/inlined_vector.h +++ b/absl/container/internal/inlined_vector.h @@ -390,25 +390,20 @@ class Storage { return data_.allocated.allocated_data; } - Pointer GetInlinedData() { - return reinterpret_cast>(data_.inlined.inlined_data); - } - - ConstPointer GetInlinedData() const { - return reinterpret_cast>(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. + // ABSL_ATTRIBUTE_NO_SANITIZE_CFI is used because the memory pointed to may be + // uninitialized, a common pattern in allocate()+construct() APIs. // https://clang.llvm.org/docs/ControlFlowIntegrity.html#bad-cast-checking // NOTE: When this was written, LLVM documentation did not explicitly // mention that casting `char*` and using `reinterpret_cast` qualifies // as a bad cast. - ABSL_ATTRIBUTE_NO_SANITIZE_CFI Pointer GetInlinedDataUninitialized() { + ABSL_ATTRIBUTE_NO_SANITIZE_CFI Pointer GetInlinedData() { return reinterpret_cast>(data_.inlined.inlined_data); } + ConstPointer GetInlinedData() const { + return reinterpret_cast>(data_.inlined.inlined_data); + } + SizeType GetAllocatedCapacity() const { return data_.allocated.allocated_capacity; } @@ -637,7 +632,7 @@ auto Storage::Initialize(ValueAdapter values, SizeType new_size) SetAllocation(allocation); SetIsAllocated(); } else { - construct_data = GetInlinedDataUninitialized(); + construct_data = GetInlinedData(); } ConstructElements(GetAllocator(), construct_data, values, new_size); -- cgit v1.2.3