From f1e94c82c94bf655ece7bffdcac916ccf42df94f Mon Sep 17 00:00:00 2001 From: "Duncan P. N. Exon Smith" Date: Wed, 2 Dec 2020 13:44:16 -0800 Subject: [PATCH] ADT: Stop peeking inside AlignedCharArrayUnion, NFC Update all the users of `AlignedCharArrayUnion` to stop peeking inside (to look at `buffer`) so that a follow-up patch can replace it with an alias to `std::aligned_union_t`. This was reviewed as part of https://reviews.llvm.org/D92512, but I'm splitting this bit out to commit first to reduce churn in case the change to `AlignedCharArrayUnion` needs to be reverted for some unexpected reason. --- include/llvm/ADT/DenseMap.h | 8 ++++---- include/llvm/ADT/IntervalMap.h | 7 ++----- include/llvm/CodeGen/DIE.h | 6 +++--- include/llvm/Support/Error.h | 8 ++++---- include/llvm/Support/ErrorOr.h | 6 +++--- include/llvm/Support/JSON.h | 4 ++-- lib/Support/JSON.cpp | 4 ++-- lib/Transforms/InstCombine/InstCombineAddSub.cpp | 8 ++++---- 8 files changed, 24 insertions(+), 27 deletions(-) diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h index 7f7a4593ae3..c9bf762a240 100644 --- a/include/llvm/ADT/DenseMap.h +++ b/include/llvm/ADT/DenseMap.h @@ -1042,7 +1042,7 @@ public: if (Small) { // First move the inline buckets into a temporary storage. AlignedCharArrayUnion TmpStorage; - BucketT *TmpBegin = reinterpret_cast(TmpStorage.buffer); + BucketT *TmpBegin = reinterpret_cast(&TmpStorage); BucketT *TmpEnd = TmpBegin; // Loop over the buckets, moving non-empty, non-tombstones into the @@ -1132,8 +1132,8 @@ private: assert(Small); // Note that this cast does not violate aliasing rules as we assert that // the memory's dynamic type is the small, inline bucket buffer, and the - // 'storage.buffer' static type is 'char *'. - return reinterpret_cast(storage.buffer); + // 'storage' is a POD containing a char buffer. + return reinterpret_cast(&storage); } BucketT *getInlineBuckets() { @@ -1144,7 +1144,7 @@ private: const LargeRep *getLargeRep() const { assert(!Small); // Note, same rule about aliasing as with getInlineBuckets. - return reinterpret_cast(storage.buffer); + return reinterpret_cast(&storage); } LargeRep *getLargeRep() { diff --git a/include/llvm/ADT/IntervalMap.h b/include/llvm/ADT/IntervalMap.h index b6c9fc79108..0b6c7d66780 100644 --- a/include/llvm/ADT/IntervalMap.h +++ b/include/llvm/ADT/IntervalMap.h @@ -978,10 +978,7 @@ private: Allocator &allocator; /// Represent data as a node type without breaking aliasing rules. - template - T &dataAs() const { - return *bit_cast(const_cast(data.buffer)); - } + template T &dataAs() const { return *bit_cast(&data); } const RootLeaf &rootLeaf() const { assert(!branched() && "Cannot acces leaf data in branched root"); @@ -1039,7 +1036,7 @@ private: public: explicit IntervalMap(Allocator &a) : height(0), rootSize(0), allocator(a) { - assert((uintptr_t(data.buffer) & (alignof(RootLeaf) - 1)) == 0 && + assert((uintptr_t(&data) & (alignof(RootLeaf) - 1)) == 0 && "Insufficient alignment"); new(&rootLeaf()) RootLeaf(); } diff --git a/include/llvm/CodeGen/DIE.h b/include/llvm/CodeGen/DIE.h index eaa700f9e1e..1667cf8cd06 100644 --- a/include/llvm/CodeGen/DIE.h +++ b/include/llvm/CodeGen/DIE.h @@ -383,12 +383,12 @@ private: static_assert(std::is_standard_layout::value || std::is_pointer::value, "Expected standard layout or pointer"); - new (reinterpret_cast(Val.buffer)) T(V); + new (reinterpret_cast(&Val)) T(V); } - template T *get() { return reinterpret_cast(Val.buffer); } + template T *get() { return reinterpret_cast(&Val); } template const T *get() const { - return reinterpret_cast(Val.buffer); + return reinterpret_cast(&Val); } template void destruct() { get()->~T(); } diff --git a/include/llvm/Support/Error.h b/include/llvm/Support/Error.h index 9dd1bb7cb96..c0f7c10aefb 100644 --- a/include/llvm/Support/Error.h +++ b/include/llvm/Support/Error.h @@ -629,22 +629,22 @@ private: storage_type *getStorage() { assert(!HasError && "Cannot get value when an error exists!"); - return reinterpret_cast(TStorage.buffer); + return reinterpret_cast(&TStorage); } const storage_type *getStorage() const { assert(!HasError && "Cannot get value when an error exists!"); - return reinterpret_cast(TStorage.buffer); + return reinterpret_cast(&TStorage); } error_type *getErrorStorage() { assert(HasError && "Cannot get error when a value exists!"); - return reinterpret_cast(ErrorStorage.buffer); + return reinterpret_cast(&ErrorStorage); } const error_type *getErrorStorage() const { assert(HasError && "Cannot get error when a value exists!"); - return reinterpret_cast(ErrorStorage.buffer); + return reinterpret_cast(&ErrorStorage); } // Used by ExpectedAsOutParameter to reset the checked flag. diff --git a/include/llvm/Support/ErrorOr.h b/include/llvm/Support/ErrorOr.h index 1fbccc1d1e2..b654c9c9c43 100644 --- a/include/llvm/Support/ErrorOr.h +++ b/include/llvm/Support/ErrorOr.h @@ -235,17 +235,17 @@ private: storage_type *getStorage() { assert(!HasError && "Cannot get value when an error exists!"); - return reinterpret_cast(TStorage.buffer); + return reinterpret_cast(&TStorage); } const storage_type *getStorage() const { assert(!HasError && "Cannot get value when an error exists!"); - return reinterpret_cast(TStorage.buffer); + return reinterpret_cast(&TStorage); } std::error_code *getErrorStorage() { assert(HasError && "Cannot get error when a value exists!"); - return reinterpret_cast(ErrorStorage.buffer); + return reinterpret_cast(&ErrorStorage); } const std::error_code *getErrorStorage() const { diff --git a/include/llvm/Support/JSON.h b/include/llvm/Support/JSON.h index 9a8f915eeef..c753cee60ec 100644 --- a/include/llvm/Support/JSON.h +++ b/include/llvm/Support/JSON.h @@ -456,12 +456,12 @@ private: friend class Object; template void create(U &&... V) { - new (reinterpret_cast(Union.buffer)) T(std::forward(V)...); + new (reinterpret_cast(&Union)) T(std::forward(V)...); } template T &as() const { // Using this two-step static_cast via void * instead of reinterpret_cast // silences a -Wstrict-aliasing false positive from GCC6 and earlier. - void *Storage = static_cast(Union.buffer); + void *Storage = static_cast(&Union); return *static_cast(Storage); } diff --git a/lib/Support/JSON.cpp b/lib/Support/JSON.cpp index 8471e5818cb..dbfd673553f 100644 --- a/lib/Support/JSON.cpp +++ b/lib/Support/JSON.cpp @@ -109,7 +109,7 @@ void Value::copyFrom(const Value &M) { case T_Boolean: case T_Double: case T_Integer: - memcpy(Union.buffer, M.Union.buffer, sizeof(Union.buffer)); + memcpy(&Union, &M.Union, sizeof(Union)); break; case T_StringRef: create(M.as()); @@ -133,7 +133,7 @@ void Value::moveFrom(const Value &&M) { case T_Boolean: case T_Double: case T_Integer: - memcpy(Union.buffer, M.Union.buffer, sizeof(Union.buffer)); + memcpy(&Union, &M.Union, sizeof(Union)); break; case T_StringRef: create(M.as()); diff --git a/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/lib/Transforms/InstCombine/InstCombineAddSub.cpp index bf356d0de94..74ba23d343a 100644 --- a/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -82,11 +82,11 @@ namespace { private: bool insaneIntVal(int V) { return V > 4 || V < -4; } - APFloat *getFpValPtr() - { return reinterpret_cast(&FpValBuf.buffer[0]); } + APFloat *getFpValPtr() { return reinterpret_cast(&FpValBuf); } - const APFloat *getFpValPtr() const - { return reinterpret_cast(&FpValBuf.buffer[0]); } + const APFloat *getFpValPtr() const { + return reinterpret_cast(&FpValBuf); + } const APFloat &getFpVal() const { assert(IsFp && BufHasFpVal && "Incorret state");