jfb created this revision.
jfb added a reviewer: chandlerc.
Herald added subscribers: llvm-commits, lldb-commits, cfe-commits, dexonsmith,
jkorous, hiraditya, javed.absar.
Herald added projects: clang, LLDB, LLVM.
jfb added a comment.
This is the main event: https://reviews.llvm.org/D65249#change-IWk6CtRl45h6
The rest is side-show.
Two things in this patch:
- Use std::aligned_storage instead of AlignedCharArray. Note: template
parameters are swapped.
- Use variadic templates in the implementation of AlignedCharArrayUnion.
The other files are changed accordingly:
- Use std::aligned_storage.
- The buffer is no longer implicitly a character array, requiring casting in
some cases.
This should be fine since our current minimum MSVC version is now Visual Studio
2017 version 15.0.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D65249
Files:
clang/include/clang/AST/APValue.h
clang/include/clang/AST/ASTContext.h
clang/include/clang/AST/ASTTypeTraits.h
clang/include/clang/AST/Expr.h
clang/include/clang/Sema/Overload.h
clang/lib/AST/APValue.cpp
clang/lib/CodeGen/CGCleanup.cpp
clang/lib/DirectoryWatcher/linux/DirectoryWatcher-linux.cpp
clang/lib/Frontend/PrecompiledPreamble.cpp
clang/lib/Sema/SemaOverload.cpp
clang/lib/Sema/TypeLocBuilder.cpp
clang/lib/Sema/TypeLocBuilder.h
lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h
llvm/include/llvm/ADT/DenseMap.h
llvm/include/llvm/ADT/IntervalMap.h
llvm/include/llvm/CodeGen/DIE.h
llvm/include/llvm/Support/AlignOf.h
llvm/include/llvm/Support/Endian.h
llvm/include/llvm/Support/Error.h
llvm/include/llvm/Support/ErrorOr.h
llvm/include/llvm/Support/JSON.h
llvm/include/llvm/Support/TrailingObjects.h
llvm/lib/Support/JSON.cpp
llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
llvm/unittests/Support/AlignOfTest.cpp
Index: llvm/unittests/Support/AlignOfTest.cpp
===================================================================
--- llvm/unittests/Support/AlignOfTest.cpp
+++ llvm/unittests/Support/AlignOfTest.cpp
@@ -233,16 +233,5 @@
#ifndef _MSC_VER
EXPECT_EQ(sizeof(V8), sizeof(AlignedCharArrayUnion<V8>));
#endif
-
- EXPECT_EQ(1u, (alignof(AlignedCharArray<1, 1>)));
- EXPECT_EQ(2u, (alignof(AlignedCharArray<2, 1>)));
- EXPECT_EQ(4u, (alignof(AlignedCharArray<4, 1>)));
- EXPECT_EQ(8u, (alignof(AlignedCharArray<8, 1>)));
- EXPECT_EQ(16u, (alignof(AlignedCharArray<16, 1>)));
-
- EXPECT_EQ(1u, sizeof(AlignedCharArray<1, 1>));
- EXPECT_EQ(7u, sizeof(AlignedCharArray<1, 7>));
- EXPECT_EQ(2u, sizeof(AlignedCharArray<2, 2>));
- EXPECT_EQ(16u, sizeof(AlignedCharArray<2, 16>));
}
} // end anonymous namespace
Index: llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -81,11 +81,13 @@
private:
bool insaneIntVal(int V) { return V > 4 || V < -4; }
- APFloat *getFpValPtr()
- { return reinterpret_cast<APFloat *>(&FpValBuf.buffer[0]); }
+ APFloat *getFpValPtr() {
+ return reinterpret_cast<APFloat *>(&FpValBuf.buffer);
+ }
- const APFloat *getFpValPtr() const
- { return reinterpret_cast<const APFloat *>(&FpValBuf.buffer[0]); }
+ const APFloat *getFpValPtr() const {
+ return reinterpret_cast<const APFloat *>(&FpValBuf.buffer);
+ }
const APFloat &getFpVal() const {
assert(IsFp && BufHasFpVal && "Incorret state");
Index: llvm/lib/Support/JSON.cpp
===================================================================
--- llvm/lib/Support/JSON.cpp
+++ llvm/lib/Support/JSON.cpp
@@ -106,7 +106,7 @@
case T_Boolean:
case T_Double:
case T_Integer:
- memcpy(Union.buffer, M.Union.buffer, sizeof(Union.buffer));
+ memcpy(&Union.buffer, &M.Union.buffer, sizeof(Union.buffer));
break;
case T_StringRef:
create<StringRef>(M.as<StringRef>());
@@ -130,7 +130,7 @@
case T_Boolean:
case T_Double:
case T_Integer:
- memcpy(Union.buffer, M.Union.buffer, sizeof(Union.buffer));
+ memcpy(&Union.buffer, &M.Union.buffer, sizeof(Union.buffer));
break;
case T_StringRef:
create<StringRef>(M.as<StringRef>());
Index: llvm/include/llvm/Support/TrailingObjects.h
===================================================================
--- llvm/include/llvm/Support/TrailingObjects.h
+++ llvm/include/llvm/Support/TrailingObjects.h
@@ -369,7 +369,7 @@
template <typename... Tys> struct FixedSizeStorage {
template <size_t... Counts> struct with_counts {
enum { Size = totalSizeToAlloc<Tys...>(Counts...) };
- typedef llvm::AlignedCharArray<alignof(BaseTy), Size> type;
+ using type = typename std::aligned_storage<Size, alignof(BaseTy)>::type;
};
};
Index: llvm/include/llvm/Support/JSON.h
===================================================================
--- llvm/include/llvm/Support/JSON.h
+++ llvm/include/llvm/Support/JSON.h
@@ -451,12 +451,12 @@
friend class Object;
template <typename T, typename... U> void create(U &&... V) {
- new (reinterpret_cast<T *>(Union.buffer)) T(std::forward<U>(V)...);
+ new (reinterpret_cast<T *>(&Union.buffer)) T(std::forward<U>(V)...);
}
template <typename T> 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<void *>(Union.buffer);
+ void *Storage = static_cast<void *>(&Union.buffer);
return *static_cast<T *>(Storage);
}
Index: llvm/include/llvm/Support/ErrorOr.h
===================================================================
--- llvm/include/llvm/Support/ErrorOr.h
+++ llvm/include/llvm/Support/ErrorOr.h
@@ -241,17 +241,17 @@
storage_type *getStorage() {
assert(!HasError && "Cannot get value when an error exists!");
- return reinterpret_cast<storage_type*>(TStorage.buffer);
+ return reinterpret_cast<storage_type *>(&TStorage.buffer);
}
const storage_type *getStorage() const {
assert(!HasError && "Cannot get value when an error exists!");
- return reinterpret_cast<const storage_type*>(TStorage.buffer);
+ return reinterpret_cast<const storage_type *>(&TStorage.buffer);
}
std::error_code *getErrorStorage() {
assert(HasError && "Cannot get error when a value exists!");
- return reinterpret_cast<std::error_code *>(ErrorStorage.buffer);
+ return reinterpret_cast<std::error_code *>(&ErrorStorage.buffer);
}
const std::error_code *getErrorStorage() const {
Index: llvm/include/llvm/Support/Error.h
===================================================================
--- llvm/include/llvm/Support/Error.h
+++ llvm/include/llvm/Support/Error.h
@@ -624,22 +624,22 @@
storage_type *getStorage() {
assert(!HasError && "Cannot get value when an error exists!");
- return reinterpret_cast<storage_type *>(TStorage.buffer);
+ return reinterpret_cast<storage_type *>(&TStorage.buffer);
}
const storage_type *getStorage() const {
assert(!HasError && "Cannot get value when an error exists!");
- return reinterpret_cast<const storage_type *>(TStorage.buffer);
+ return reinterpret_cast<const storage_type *>(&TStorage.buffer);
}
error_type *getErrorStorage() {
assert(HasError && "Cannot get error when a value exists!");
- return reinterpret_cast<error_type *>(ErrorStorage.buffer);
+ return reinterpret_cast<error_type *>(&ErrorStorage.buffer);
}
const error_type *getErrorStorage() const {
assert(HasError && "Cannot get error when a value exists!");
- return reinterpret_cast<const error_type *>(ErrorStorage.buffer);
+ return reinterpret_cast<const error_type *>(&ErrorStorage.buffer);
}
// Used by ExpectedAsOutParameter to reset the checked flag.
Index: llvm/include/llvm/Support/Endian.h
===================================================================
--- llvm/include/llvm/Support/Endian.h
+++ llvm/include/llvm/Support/Endian.h
@@ -216,13 +216,11 @@
explicit packed_endian_specific_integral(value_type val) { *this = val; }
operator value_type() const {
- return endian::read<value_type, endian, alignment>(
- (const void*)Value.buffer);
+ return endian::read<value_type, endian, alignment>((const void *)&Value);
}
void operator=(value_type newValue) {
- endian::write<value_type, endian, alignment>(
- (void*)Value.buffer, newValue);
+ endian::write<value_type, endian, alignment>((void *)&Value, newValue);
}
packed_endian_specific_integral &operator+=(value_type newValue) {
@@ -246,8 +244,9 @@
}
private:
- AlignedCharArray<PickAlignment<value_type, alignment>::value,
- sizeof(value_type)> Value;
+ typename std::aligned_storage<
+ sizeof(value_type), PickAlignment<value_type, alignment>::value>::type
+ Value;
public:
struct ref {
Index: llvm/include/llvm/Support/AlignOf.h
===================================================================
--- llvm/include/llvm/Support/AlignOf.h
+++ llvm/include/llvm/Support/AlignOf.h
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines the AlignedCharArray and AlignedCharArrayUnion classes.
+// This file defines the AlignedCharArrayUnion classes.
//
//===----------------------------------------------------------------------===//
@@ -15,130 +15,42 @@
#include "llvm/Support/Compiler.h"
#include <cstddef>
+#include <type_traits>
namespace llvm {
-/// \struct AlignedCharArray
-/// Helper for building an aligned character array type.
-///
-/// This template is used to explicitly build up a collection of aligned
-/// character array types. We have to build these up using a macro and explicit
-/// specialization to cope with MSVC (at least till 2015) where only an
-/// integer literal can be used to specify an alignment constraint. Once built
-/// up here, we can then begin to indirect between these using normal C++
-/// template parameters.
-
-// MSVC requires special handling here.
-#ifndef _MSC_VER
-
-template<std::size_t Alignment, std::size_t Size>
-struct AlignedCharArray {
- alignas(Alignment) char buffer[Size];
-};
-
-#else // _MSC_VER
-
-/// Create a type with an aligned char buffer.
-template<std::size_t Alignment, std::size_t Size>
-struct AlignedCharArray;
-
-// We provide special variations of this template for the most common
-// alignments because __declspec(align(...)) doesn't actually work when it is
-// a member of a by-value function argument in MSVC, even if the alignment
-// request is something reasonably like 8-byte or 16-byte. Note that we can't
-// even include the declspec with the union that forces the alignment because
-// MSVC warns on the existence of the declspec despite the union member forcing
-// proper alignment.
-
-template<std::size_t Size>
-struct AlignedCharArray<1, Size> {
- union {
- char aligned;
- char buffer[Size];
- };
-};
-
-template<std::size_t Size>
-struct AlignedCharArray<2, Size> {
- union {
- short aligned;
- char buffer[Size];
- };
-};
-
-template<std::size_t Size>
-struct AlignedCharArray<4, Size> {
- union {
- int aligned;
- char buffer[Size];
- };
-};
+namespace detail {
+template <typename T, typename... Ts> class AlignerImpl {
+ T t;
+ AlignerImpl<Ts...> rest;
-template<std::size_t Size>
-struct AlignedCharArray<8, Size> {
- union {
- double aligned;
- char buffer[Size];
- };
+ AlignerImpl() = delete;
};
-
-// The rest of these are provided with a __declspec(align(...)) and we simply
-// can't pass them by-value as function arguments on MSVC.
-
-#define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
- template<std::size_t Size> \
- struct AlignedCharArray<x, Size> { \
- __declspec(align(x)) char buffer[Size]; \
- };
-
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16)
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32)
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64)
-LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128)
-
-#undef LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT
-
-#endif // _MSC_VER
-
-namespace detail {
-template <typename T1,
- typename T2 = char, typename T3 = char, typename T4 = char,
- typename T5 = char, typename T6 = char, typename T7 = char,
- typename T8 = char, typename T9 = char, typename T10 = char>
-class AlignerImpl {
- T1 t1; T2 t2; T3 t3; T4 t4; T5 t5; T6 t6; T7 t7; T8 t8; T9 t9; T10 t10;
+template <typename T> class AlignerImpl<T> {
+ T t;
AlignerImpl() = delete;
};
-template <typename T1,
- typename T2 = char, typename T3 = char, typename T4 = char,
- typename T5 = char, typename T6 = char, typename T7 = char,
- typename T8 = char, typename T9 = char, typename T10 = char>
-union SizerImpl {
- char arr1[sizeof(T1)], arr2[sizeof(T2)], arr3[sizeof(T3)], arr4[sizeof(T4)],
- arr5[sizeof(T5)], arr6[sizeof(T6)], arr7[sizeof(T7)], arr8[sizeof(T8)],
- arr9[sizeof(T9)], arr10[sizeof(T10)];
+template <typename T, typename... Ts> union SizerImpl {
+ char arr[sizeof(T)];
+ SizerImpl<Ts...> rest;
};
+
+template <typename T> union SizerImpl<T> { char arr[sizeof(T)]; };
} // end namespace detail
-/// This union template exposes a suitably aligned and sized character
-/// array member which can hold elements of any of up to ten types.
+/// A suitably aligned and sized character array member which can hold elements
+/// of any type.
///
-/// These types may be arrays, structs, or any other types. The goal is to
-/// expose a char array buffer member which can be used as suitable storage for
-/// a placement new of any of these types. Support for more than ten types can
-/// be added at the cost of more boilerplate.
-template <typename T1,
- typename T2 = char, typename T3 = char, typename T4 = char,
- typename T5 = char, typename T6 = char, typename T7 = char,
- typename T8 = char, typename T9 = char, typename T10 = char>
-struct AlignedCharArrayUnion : llvm::AlignedCharArray<
- alignof(llvm::detail::AlignerImpl<T1, T2, T3, T4, T5,
- T6, T7, T8, T9, T10>),
- sizeof(::llvm::detail::SizerImpl<T1, T2, T3, T4, T5,
- T6, T7, T8, T9, T10>)> {
+/// These types may be arrays, structs, or any other types. This exposes a
+/// `buffer` member which can be used as suitable storage for a placement new of
+/// any of these types.
+template <typename T, typename... Ts> struct AlignedCharArrayUnion {
+ typename std::aligned_storage<
+ sizeof(llvm::detail::SizerImpl<T, Ts...>),
+ alignof(::llvm::detail::AlignerImpl<T, Ts...>)>::type buffer;
};
} // end namespace llvm
Index: llvm/include/llvm/CodeGen/DIE.h
===================================================================
--- llvm/include/llvm/CodeGen/DIE.h
+++ llvm/include/llvm/CodeGen/DIE.h
@@ -382,12 +382,12 @@
static_assert(std::is_standard_layout<T>::value ||
std::is_pointer<T>::value,
"Expected standard layout or pointer");
- new (reinterpret_cast<void *>(Val.buffer)) T(V);
+ new (reinterpret_cast<void *>(&Val.buffer)) T(V);
}
- template <class T> T *get() { return reinterpret_cast<T *>(Val.buffer); }
+ template <class T> T *get() { return reinterpret_cast<T *>(&Val.buffer); }
template <class T> const T *get() const {
- return reinterpret_cast<const T *>(Val.buffer);
+ return reinterpret_cast<const T *>(&Val.buffer);
}
template <class T> void destruct() { get<T>()->~T(); }
Index: llvm/include/llvm/ADT/IntervalMap.h
===================================================================
--- llvm/include/llvm/ADT/IntervalMap.h
+++ llvm/include/llvm/ADT/IntervalMap.h
@@ -981,7 +981,8 @@
/// Represent data as a node type without breaking aliasing rules.
template <typename T>
T &dataAs() const {
- return *bit_cast<T *>(const_cast<char *>(data.buffer));
+ return *bit_cast<T *>(
+ const_cast<char *>(reinterpret_cast<const char *>(&data.buffer)));
}
const RootLeaf &rootLeaf() const {
@@ -1040,7 +1041,7 @@
public:
explicit IntervalMap(Allocator &a) : height(0), rootSize(0), allocator(a) {
- assert((uintptr_t(data.buffer) & (alignof(RootLeaf) - 1)) == 0 &&
+ assert((uintptr_t(&data.buffer) & (alignof(RootLeaf) - 1)) == 0 &&
"Insufficient alignment");
new(&rootLeaf()) RootLeaf();
}
Index: llvm/include/llvm/ADT/DenseMap.h
===================================================================
--- llvm/include/llvm/ADT/DenseMap.h
+++ llvm/include/llvm/ADT/DenseMap.h
@@ -1037,7 +1037,7 @@
// First move the inline buckets into a temporary storage.
AlignedCharArrayUnion<BucketT[InlineBuckets]> TmpStorage;
- BucketT *TmpBegin = reinterpret_cast<BucketT *>(TmpStorage.buffer);
+ BucketT *TmpBegin = reinterpret_cast<BucketT *>(&TmpStorage.buffer);
BucketT *TmpEnd = TmpBegin;
// Loop over the buckets, moving non-empty, non-tombstones into the
@@ -1124,7 +1124,7 @@
// 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<const BucketT *>(storage.buffer);
+ return reinterpret_cast<const BucketT *>(&storage.buffer);
}
BucketT *getInlineBuckets() {
@@ -1135,7 +1135,7 @@
const LargeRep *getLargeRep() const {
assert(!Small);
// Note, same rule about aliasing as with getInlineBuckets.
- return reinterpret_cast<const LargeRep *>(storage.buffer);
+ return reinterpret_cast<const LargeRep *>(&storage.buffer);
}
LargeRep *getLargeRep() {
Index: lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h
===================================================================
--- lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h
+++ lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h
@@ -73,7 +73,7 @@
};
struct VReg {
- llvm::AlignedCharArray<16, 16> bytes;
+ std::aligned_storage<16, 16>::type bytes;
};
// mirrors <mach/arm/thread_status.h> arm_neon_state64_t
Index: lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
===================================================================
--- lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
+++ lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp
@@ -424,7 +424,7 @@
case fpu_v29:
case fpu_v30:
case fpu_v31:
- value.SetBytes(fpu.v[reg - fpu_v0].bytes.buffer, reg_info->byte_size,
+ value.SetBytes(&fpu.v[reg - fpu_v0].bytes.buffer, reg_info->byte_size,
endian::InlHostByteOrder());
break;
@@ -616,7 +616,7 @@
case fpu_v29:
case fpu_v30:
case fpu_v31:
- ::memcpy(fpu.v[reg - fpu_v0].bytes.buffer, value.GetBytes(),
+ ::memcpy(&fpu.v[reg - fpu_v0].bytes.buffer, value.GetBytes(),
value.GetByteSize());
break;
Index: clang/lib/Sema/TypeLocBuilder.h
===================================================================
--- clang/lib/Sema/TypeLocBuilder.h
+++ clang/lib/Sema/TypeLocBuilder.h
@@ -39,19 +39,18 @@
/// The inline buffer.
enum { BufferMaxAlignment = alignof(void *) };
- llvm::AlignedCharArray<BufferMaxAlignment, InlineCapacity> InlineBuffer;
+ std::aligned_storage<InlineCapacity, BufferMaxAlignment>::type InlineBuffer;
unsigned NumBytesAtAlign4, NumBytesAtAlign8;
public:
- TypeLocBuilder()
- : Buffer(InlineBuffer.buffer), Capacity(InlineCapacity),
- Index(InlineCapacity), NumBytesAtAlign4(0), NumBytesAtAlign8(0)
- {
- }
-
- ~TypeLocBuilder() {
- if (Buffer != InlineBuffer.buffer)
- delete[] Buffer;
+ TypeLocBuilder()
+ : Buffer(reinterpret_cast<char *>(&InlineBuffer)),
+ Capacity(InlineCapacity), Index(InlineCapacity), NumBytesAtAlign4(0),
+ NumBytesAtAlign8(0) {}
+
+ ~TypeLocBuilder() {
+ if (Buffer != reinterpret_cast<char *>(&InlineBuffer))
+ delete[] Buffer;
}
/// Ensures that this buffer has at least as much capacity as described.
Index: clang/lib/Sema/TypeLocBuilder.cpp
===================================================================
--- clang/lib/Sema/TypeLocBuilder.cpp
+++ clang/lib/Sema/TypeLocBuilder.cpp
@@ -51,7 +51,7 @@
&Buffer[Index],
Capacity - Index);
- if (Buffer != InlineBuffer.buffer)
+ if (Buffer != reinterpret_cast<char *>(&InlineBuffer))
delete[] Buffer;
Buffer = NewBuffer;
Index: clang/lib/Sema/SemaOverload.cpp
===================================================================
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -7052,10 +7052,10 @@
// allocator).
QualType CallResultType = ConversionType.getNonLValueExprType(Context);
- llvm::AlignedCharArray<alignof(CallExpr), sizeof(CallExpr) + sizeof(Stmt *)>
- Buffer;
+ std::aligned_storage<sizeof(CallExpr) + sizeof(Stmt *),
+ alignof(CallExpr)>::type Buffer;
CallExpr *TheTemporaryCall = CallExpr::CreateTemporary(
- Buffer.buffer, &ConversionFn, CallResultType, VK, From->getBeginLoc());
+ &Buffer, &ConversionFn, CallResultType, VK, From->getBeginLoc());
ImplicitConversionSequence ICS =
TryCopyInitialization(*this, TheTemporaryCall, ToType,
Index: clang/lib/Frontend/PrecompiledPreamble.cpp
===================================================================
--- clang/lib/Frontend/PrecompiledPreamble.cpp
+++ clang/lib/Frontend/PrecompiledPreamble.cpp
@@ -637,7 +637,7 @@
PrecompiledPreamble::TempPCHFile &PrecompiledPreamble::PCHStorage::asFile() {
assert(getKind() == Kind::TempFile);
- return *reinterpret_cast<TempPCHFile *>(Storage.buffer);
+ return *reinterpret_cast<TempPCHFile *>(&Storage.buffer);
}
const PrecompiledPreamble::TempPCHFile &
@@ -648,7 +648,7 @@
PrecompiledPreamble::InMemoryPreamble &
PrecompiledPreamble::PCHStorage::asMemory() {
assert(getKind() == Kind::InMemory);
- return *reinterpret_cast<InMemoryPreamble *>(Storage.buffer);
+ return *reinterpret_cast<InMemoryPreamble *>(&Storage.buffer);
}
const PrecompiledPreamble::InMemoryPreamble &
Index: clang/lib/DirectoryWatcher/linux/DirectoryWatcher-linux.cpp
===================================================================
--- clang/lib/DirectoryWatcher/linux/DirectoryWatcher-linux.cpp
+++ clang/lib/DirectoryWatcher/linux/DirectoryWatcher-linux.cpp
@@ -184,10 +184,9 @@
// the inotify file descriptor should have the same alignment as
// struct inotify_event.
- auto ManagedBuffer =
- llvm::make_unique<llvm::AlignedCharArray<alignof(struct inotify_event),
- EventBufferLength>>();
- char *const Buf = ManagedBuffer->buffer;
+ auto ManagedBuffer = llvm::make_unique<std::aligned_storage<
+ EventBufferLength, alignof(struct inotify_event)>::type>();
+ char *const Buf = ManagedBuffer.get();
const int EpollFD = epoll_create1(EPOLL_CLOEXEC);
if (EpollFD == -1) {
@@ -350,4 +349,4 @@
return llvm::make_unique<DirectoryWatcherLinux>(
Path, Receiver, WaitForInitialSync, InotifyFD, InotifyWD,
std::move(*InotifyPollingStopper));
-}
\ No newline at end of file
+}
Index: clang/lib/CodeGen/CGCleanup.cpp
===================================================================
--- clang/lib/CodeGen/CGCleanup.cpp
+++ clang/lib/CodeGen/CGCleanup.cpp
@@ -740,14 +740,16 @@
// here. Unfortunately, if you ask for a SmallVector<char>, the
// alignment isn't sufficient.
auto *CleanupSource = reinterpret_cast<char *>(Scope.getCleanupBuffer());
- llvm::AlignedCharArray<EHScopeStack::ScopeStackAlignment, 8 * sizeof(void *)> CleanupBufferStack;
+ std::aligned_storage<8 * sizeof(void *),
+ EHScopeStack::ScopeStackAlignment>::type
+ CleanupBufferStack;
std::unique_ptr<char[]> CleanupBufferHeap;
size_t CleanupSize = Scope.getCleanupSize();
EHScopeStack::Cleanup *Fn;
if (CleanupSize <= sizeof(CleanupBufferStack)) {
- memcpy(CleanupBufferStack.buffer, CleanupSource, CleanupSize);
- Fn = reinterpret_cast<EHScopeStack::Cleanup *>(CleanupBufferStack.buffer);
+ memcpy(&CleanupBufferStack, CleanupSource, CleanupSize);
+ Fn = reinterpret_cast<EHScopeStack::Cleanup *>(&CleanupBufferStack);
} else {
CleanupBufferHeap.reset(new char[CleanupSize]);
memcpy(CleanupBufferHeap.get(), CleanupSource, CleanupSize);
Index: clang/lib/AST/APValue.cpp
===================================================================
--- clang/lib/AST/APValue.cpp
+++ clang/lib/AST/APValue.cpp
@@ -240,7 +240,7 @@
}
case Vector:
MakeVector();
- setVector(((const Vec *)(const char *)RHS.Data.buffer)->Elts,
+ setVector(((const Vec *)(const char *)&RHS.Data.buffer)->Elts,
RHS.getVectorLength());
break;
case ComplexInt:
@@ -292,29 +292,29 @@
void APValue::DestroyDataAndMakeUninit() {
if (Kind == Int)
- ((APSInt*)(char*)Data.buffer)->~APSInt();
+ ((APSInt *)(char *)&Data.buffer)->~APSInt();
else if (Kind == Float)
- ((APFloat*)(char*)Data.buffer)->~APFloat();
+ ((APFloat *)(char *)&Data.buffer)->~APFloat();
else if (Kind == FixedPoint)
- ((APFixedPoint *)(char *)Data.buffer)->~APFixedPoint();
+ ((APFixedPoint *)(char *)&Data.buffer)->~APFixedPoint();
else if (Kind == Vector)
- ((Vec*)(char*)Data.buffer)->~Vec();
+ ((Vec *)(char *)&Data.buffer)->~Vec();
else if (Kind == ComplexInt)
- ((ComplexAPSInt*)(char*)Data.buffer)->~ComplexAPSInt();
+ ((ComplexAPSInt *)(char *)&Data.buffer)->~ComplexAPSInt();
else if (Kind == ComplexFloat)
- ((ComplexAPFloat*)(char*)Data.buffer)->~ComplexAPFloat();
+ ((ComplexAPFloat *)(char *)&Data.buffer)->~ComplexAPFloat();
else if (Kind == LValue)
- ((LV*)(char*)Data.buffer)->~LV();
+ ((LV *)(char *)&Data.buffer)->~LV();
else if (Kind == Array)
- ((Arr*)(char*)Data.buffer)->~Arr();
+ ((Arr *)(char *)&Data.buffer)->~Arr();
else if (Kind == Struct)
- ((StructData*)(char*)Data.buffer)->~StructData();
+ ((StructData *)(char *)&Data.buffer)->~StructData();
else if (Kind == Union)
- ((UnionData*)(char*)Data.buffer)->~UnionData();
+ ((UnionData *)(char *)&Data.buffer)->~UnionData();
else if (Kind == MemberPointer)
- ((MemberPointerData*)(char*)Data.buffer)->~MemberPointerData();
+ ((MemberPointerData *)(char *)&Data.buffer)->~MemberPointerData();
else if (Kind == AddrLabelDiff)
- ((AddrLabelDiffData*)(char*)Data.buffer)->~AddrLabelDiffData();
+ ((AddrLabelDiffData *)(char *)&Data.buffer)->~AddrLabelDiffData();
Kind = None;
}
@@ -348,9 +348,9 @@
"same size.");
return getComplexIntReal().needsCleanup();
case LValue:
- return reinterpret_cast<const LV *>(Data.buffer)->hasPathPtr();
+ return reinterpret_cast<const LV *>(&Data.buffer)->hasPathPtr();
case MemberPointer:
- return reinterpret_cast<const MemberPointerData *>(Data.buffer)
+ return reinterpret_cast<const MemberPointerData *>(&Data.buffer)
->hasPathPtr();
}
llvm_unreachable("Unknown APValue kind!");
@@ -359,9 +359,9 @@
void APValue::swap(APValue &RHS) {
std::swap(Kind, RHS.Kind);
char TmpData[DataSize];
- memcpy(TmpData, Data.buffer, DataSize);
- memcpy(Data.buffer, RHS.Data.buffer, DataSize);
- memcpy(RHS.Data.buffer, TmpData, DataSize);
+ memcpy(TmpData, &Data.buffer, DataSize);
+ memcpy(&Data.buffer, &RHS.Data.buffer, DataSize);
+ memcpy(&RHS.Data.buffer, TmpData, DataSize);
}
LLVM_DUMP_METHOD void APValue::dump() const {
@@ -706,49 +706,49 @@
const APValue::LValueBase APValue::getLValueBase() const {
assert(isLValue() && "Invalid accessor");
- return ((const LV*)(const void*)Data.buffer)->Base;
+ return ((const LV *)(const void *)&Data.buffer)->Base;
}
bool APValue::isLValueOnePastTheEnd() const {
assert(isLValue() && "Invalid accessor");
- return ((const LV*)(const void*)Data.buffer)->IsOnePastTheEnd;
+ return ((const LV *)(const void *)&Data.buffer)->IsOnePastTheEnd;
}
CharUnits &APValue::getLValueOffset() {
assert(isLValue() && "Invalid accessor");
- return ((LV*)(void*)Data.buffer)->Offset;
+ return ((LV *)(void *)&Data.buffer)->Offset;
}
bool APValue::hasLValuePath() const {
assert(isLValue() && "Invalid accessor");
- return ((const LV*)(const char*)Data.buffer)->hasPath();
+ return ((const LV *)(const char *)&Data.buffer)->hasPath();
}
ArrayRef<APValue::LValuePathEntry> APValue::getLValuePath() const {
assert(isLValue() && hasLValuePath() && "Invalid accessor");
- const LV &LVal = *((const LV*)(const char*)Data.buffer);
+ const LV &LVal = *((const LV *)(const char *)&Data.buffer);
return llvm::makeArrayRef(LVal.getPath(), LVal.PathLength);
}
unsigned APValue::getLValueCallIndex() const {
assert(isLValue() && "Invalid accessor");
- return ((const LV*)(const char*)Data.buffer)->Base.getCallIndex();
+ return ((const LV *)(const char *)&Data.buffer)->Base.getCallIndex();
}
unsigned APValue::getLValueVersion() const {
assert(isLValue() && "Invalid accessor");
- return ((const LV*)(const char*)Data.buffer)->Base.getVersion();
+ return ((const LV *)(const char *)&Data.buffer)->Base.getVersion();
}
bool APValue::isNullPointer() const {
assert(isLValue() && "Invalid usage");
- return ((const LV*)(const char*)Data.buffer)->IsNullPtr;
+ return ((const LV *)(const char *)&Data.buffer)->IsNullPtr;
}
void APValue::setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
bool IsNullPtr) {
assert(isLValue() && "Invalid accessor");
- LV &LVal = *((LV*)(char*)Data.buffer);
+ LV &LVal = *((LV *)(char *)&Data.buffer);
LVal.Base = B;
LVal.IsOnePastTheEnd = false;
LVal.Offset = O;
@@ -760,7 +760,7 @@
ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd,
bool IsNullPtr) {
assert(isLValue() && "Invalid accessor");
- LV &LVal = *((LV*)(char*)Data.buffer);
+ LV &LVal = *((LV *)(char *)&Data.buffer);
LVal.Base = B;
LVal.IsOnePastTheEnd = IsOnePastTheEnd;
LVal.Offset = O;
@@ -772,41 +772,41 @@
const ValueDecl *APValue::getMemberPointerDecl() const {
assert(isMemberPointer() && "Invalid accessor");
const MemberPointerData &MPD =
- *((const MemberPointerData *)(const char *)Data.buffer);
+ *((const MemberPointerData *)(const char *)&Data.buffer);
return MPD.MemberAndIsDerivedMember.getPointer();
}
bool APValue::isMemberPointerToDerivedMember() const {
assert(isMemberPointer() && "Invalid accessor");
const MemberPointerData &MPD =
- *((const MemberPointerData *)(const char *)Data.buffer);
+ *((const MemberPointerData *)(const char *)&Data.buffer);
return MPD.MemberAndIsDerivedMember.getInt();
}
ArrayRef<const CXXRecordDecl*> APValue::getMemberPointerPath() const {
assert(isMemberPointer() && "Invalid accessor");
const MemberPointerData &MPD =
- *((const MemberPointerData *)(const char *)Data.buffer);
+ *((const MemberPointerData *)(const char *)&Data.buffer);
return llvm::makeArrayRef(MPD.getPath(), MPD.PathLength);
}
void APValue::MakeLValue() {
assert(isAbsent() && "Bad state change");
static_assert(sizeof(LV) <= DataSize, "LV too big");
- new ((void*)(char*)Data.buffer) LV();
+ new ((void *)(char *)&Data.buffer) LV();
Kind = LValue;
}
void APValue::MakeArray(unsigned InitElts, unsigned Size) {
assert(isAbsent() && "Bad state change");
- new ((void*)(char*)Data.buffer) Arr(InitElts, Size);
+ new ((void *)(char *)&Data.buffer) Arr(InitElts, Size);
Kind = Array;
}
void APValue::MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
ArrayRef<const CXXRecordDecl*> Path) {
assert(isAbsent() && "Bad state change");
- MemberPointerData *MPD = new ((void*)(char*)Data.buffer) MemberPointerData;
+ MemberPointerData *MPD = new ((void *)(char *)&Data.buffer) MemberPointerData;
Kind = MemberPointer;
MPD->MemberAndIsDerivedMember.setPointer(Member);
MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember);
Index: clang/include/clang/Sema/Overload.h
===================================================================
--- clang/include/clang/Sema/Overload.h
+++ clang/include/clang/Sema/Overload.h
@@ -881,7 +881,7 @@
constexpr static unsigned NumInlineBytes =
24 * sizeof(ImplicitConversionSequence);
unsigned NumInlineBytesUsed = 0;
- llvm::AlignedCharArray<alignof(void *), NumInlineBytes> InlineSpace;
+ std::aligned_storage<NumInlineBytes, alignof(void *)>::type InlineSpace;
// Address space of the object being constructed.
LangAS DestAS = LangAS::Default;
@@ -904,7 +904,8 @@
unsigned NBytes = sizeof(T) * N;
if (NBytes > NumInlineBytes - NumInlineBytesUsed)
return SlabAllocator.Allocate<T>(N);
- char *FreeSpaceStart = InlineSpace.buffer + NumInlineBytesUsed;
+ char *FreeSpaceStart =
+ reinterpret_cast<char *>(&InlineSpace) + NumInlineBytesUsed;
assert(uintptr_t(FreeSpaceStart) % alignof(void *) == 0 &&
"Misaligned storage!");
Index: clang/include/clang/AST/Expr.h
===================================================================
--- clang/include/clang/AST/Expr.h
+++ clang/include/clang/AST/Expr.h
@@ -2619,9 +2619,9 @@
/// + sizeof(Stmt *) bytes of storage, aligned to alignof(CallExpr):
///
/// \code{.cpp}
- /// llvm::AlignedCharArray<alignof(CallExpr),
- /// sizeof(CallExpr) + sizeof(Stmt *)> Buffer;
- /// CallExpr *TheCall = CallExpr::CreateTemporary(Buffer.buffer, etc);
+ /// std::aligned_storage<sizeof(CallExpr) + sizeof(Stmt *),
+ /// alignof(CallExpr)>::type Buffer;
+ /// CallExpr *TheCall = CallExpr::CreateTemporary(Buffer, etc);
/// \endcode
static CallExpr *CreateTemporary(void *Mem, Expr *Fn, QualType Ty,
ExprValueKind VK, SourceLocation RParenLoc,
Index: clang/include/clang/AST/ASTTypeTraits.h
===================================================================
--- clang/include/clang/AST/ASTTypeTraits.h
+++ clang/include/clang/AST/ASTTypeTraits.h
@@ -249,7 +249,7 @@
/// use the pointer outside the scope of the DynTypedNode.
template <typename T>
const T *get() const {
- return BaseConverter<T>::get(NodeKind, Storage.buffer);
+ return BaseConverter<T>::get(NodeKind, (const char *)&Storage.buffer);
}
/// Retrieve the stored node as type \c T.
@@ -257,7 +257,8 @@
/// Similar to \c get(), but asserts that the type is what we are expecting.
template <typename T>
const T &getUnchecked() const {
- return BaseConverter<T>::getUnchecked(NodeKind, Storage.buffer);
+ return BaseConverter<T>::getUnchecked(NodeKind,
+ (const char *)&Storage.buffer);
}
ASTNodeKind getNodeKind() const { return NodeKind; }
@@ -269,7 +270,7 @@
/// method returns NULL.
const void *getMemoizationData() const {
return NodeKind.hasPointerIdentity()
- ? *reinterpret_cast<void *const *>(Storage.buffer)
+ ? *reinterpret_cast<void *const *>(&Storage.buffer)
: nullptr;
}
@@ -404,7 +405,7 @@
static DynTypedNode create(const BaseT &Node) {
DynTypedNode Result;
Result.NodeKind = ASTNodeKind::getFromNode(Node);
- new (Result.Storage.buffer) const void *(&Node);
+ new (&Result.Storage.buffer) const void *(&Node);
return Result;
}
};
@@ -424,7 +425,7 @@
static DynTypedNode create(const T &Node) {
DynTypedNode Result;
Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
- new (Result.Storage.buffer) const void *(&Node);
+ new (&Result.Storage.buffer) const void *(&Node);
return Result;
}
};
@@ -443,7 +444,7 @@
static DynTypedNode create(const T &Node) {
DynTypedNode Result;
Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
- new (Result.Storage.buffer) T(Node);
+ new (&Result.Storage.buffer) T(Node);
return Result;
}
};
Index: clang/include/clang/AST/ASTContext.h
===================================================================
--- clang/include/clang/AST/ASTContext.h
+++ clang/include/clang/AST/ASTContext.h
@@ -584,25 +584,25 @@
public:
DynTypedNodeList(const DynTypedNode &N) : IsSingleNode(true) {
- new (Storage.buffer) DynTypedNode(N);
+ new (&Storage.buffer) DynTypedNode(N);
}
DynTypedNodeList(ArrayRef<DynTypedNode> A) : IsSingleNode(false) {
- new (Storage.buffer) ArrayRef<DynTypedNode>(A);
+ new (&Storage.buffer) ArrayRef<DynTypedNode>(A);
}
const ast_type_traits::DynTypedNode *begin() const {
if (!IsSingleNode)
- return reinterpret_cast<const ArrayRef<DynTypedNode> *>(Storage.buffer)
+ return reinterpret_cast<const ArrayRef<DynTypedNode> *>(&Storage.buffer)
->begin();
- return reinterpret_cast<const DynTypedNode *>(Storage.buffer);
+ return reinterpret_cast<const DynTypedNode *>(&Storage.buffer);
}
const ast_type_traits::DynTypedNode *end() const {
if (!IsSingleNode)
- return reinterpret_cast<const ArrayRef<DynTypedNode> *>(Storage.buffer)
+ return reinterpret_cast<const ArrayRef<DynTypedNode> *>(&Storage.buffer)
->end();
- return reinterpret_cast<const DynTypedNode *>(Storage.buffer) + 1;
+ return reinterpret_cast<const DynTypedNode *>(&Storage.buffer) + 1;
}
size_t size() const { return end() - begin(); }
Index: clang/include/clang/AST/APValue.h
===================================================================
--- clang/include/clang/AST/APValue.h
+++ clang/include/clang/AST/APValue.h
@@ -335,7 +335,7 @@
APSInt &getInt() {
assert(isInt() && "Invalid accessor");
- return *(APSInt*)(char*)Data.buffer;
+ return *(APSInt *)(char *)&Data.buffer;
}
const APSInt &getInt() const {
return const_cast<APValue*>(this)->getInt();
@@ -349,7 +349,7 @@
APFloat &getFloat() {
assert(isFloat() && "Invalid accessor");
- return *(APFloat*)(char*)Data.buffer;
+ return *(APFloat *)(char *)&Data.buffer;
}
const APFloat &getFloat() const {
return const_cast<APValue*>(this)->getFloat();
@@ -357,7 +357,7 @@
APFixedPoint &getFixedPoint() {
assert(isFixedPoint() && "Invalid accessor");
- return *(APFixedPoint *)(char *)Data.buffer;
+ return *(APFixedPoint *)(char *)&Data.buffer;
}
const APFixedPoint &getFixedPoint() const {
return const_cast<APValue *>(this)->getFixedPoint();
@@ -365,7 +365,7 @@
APSInt &getComplexIntReal() {
assert(isComplexInt() && "Invalid accessor");
- return ((ComplexAPSInt*)(char*)Data.buffer)->Real;
+ return ((ComplexAPSInt *)(char *)&Data.buffer)->Real;
}
const APSInt &getComplexIntReal() const {
return const_cast<APValue*>(this)->getComplexIntReal();
@@ -373,7 +373,7 @@
APSInt &getComplexIntImag() {
assert(isComplexInt() && "Invalid accessor");
- return ((ComplexAPSInt*)(char*)Data.buffer)->Imag;
+ return ((ComplexAPSInt *)(char *)&Data.buffer)->Imag;
}
const APSInt &getComplexIntImag() const {
return const_cast<APValue*>(this)->getComplexIntImag();
@@ -381,7 +381,7 @@
APFloat &getComplexFloatReal() {
assert(isComplexFloat() && "Invalid accessor");
- return ((ComplexAPFloat*)(char*)Data.buffer)->Real;
+ return ((ComplexAPFloat *)(char *)&Data.buffer)->Real;
}
const APFloat &getComplexFloatReal() const {
return const_cast<APValue*>(this)->getComplexFloatReal();
@@ -389,7 +389,7 @@
APFloat &getComplexFloatImag() {
assert(isComplexFloat() && "Invalid accessor");
- return ((ComplexAPFloat*)(char*)Data.buffer)->Imag;
+ return ((ComplexAPFloat *)(char *)&Data.buffer)->Imag;
}
const APFloat &getComplexFloatImag() const {
return const_cast<APValue*>(this)->getComplexFloatImag();
@@ -410,20 +410,20 @@
APValue &getVectorElt(unsigned I) {
assert(isVector() && "Invalid accessor");
assert(I < getVectorLength() && "Index out of range");
- return ((Vec*)(char*)Data.buffer)->Elts[I];
+ return ((Vec *)(char *)&Data.buffer)->Elts[I];
}
const APValue &getVectorElt(unsigned I) const {
return const_cast<APValue*>(this)->getVectorElt(I);
}
unsigned getVectorLength() const {
assert(isVector() && "Invalid accessor");
- return ((const Vec*)(const void *)Data.buffer)->NumElts;
+ return ((const Vec *)(const void *)&Data.buffer)->NumElts;
}
APValue &getArrayInitializedElt(unsigned I) {
assert(isArray() && "Invalid accessor");
assert(I < getArrayInitializedElts() && "Index out of range");
- return ((Arr*)(char*)Data.buffer)->Elts[I];
+ return ((Arr *)(char *)&Data.buffer)->Elts[I];
}
const APValue &getArrayInitializedElt(unsigned I) const {
return const_cast<APValue*>(this)->getArrayInitializedElt(I);
@@ -434,35 +434,35 @@
APValue &getArrayFiller() {
assert(isArray() && "Invalid accessor");
assert(hasArrayFiller() && "No array filler");
- return ((Arr*)(char*)Data.buffer)->Elts[getArrayInitializedElts()];
+ return ((Arr *)(char *)&Data.buffer)->Elts[getArrayInitializedElts()];
}
const APValue &getArrayFiller() const {
return const_cast<APValue*>(this)->getArrayFiller();
}
unsigned getArrayInitializedElts() const {
assert(isArray() && "Invalid accessor");
- return ((const Arr*)(const void *)Data.buffer)->NumElts;
+ return ((const Arr *)(const void *)&Data.buffer)->NumElts;
}
unsigned getArraySize() const {
assert(isArray() && "Invalid accessor");
- return ((const Arr*)(const void *)Data.buffer)->ArrSize;
+ return ((const Arr *)(const void *)&Data.buffer)->ArrSize;
}
unsigned getStructNumBases() const {
assert(isStruct() && "Invalid accessor");
- return ((const StructData*)(const char*)Data.buffer)->NumBases;
+ return ((const StructData *)(const char *)&Data.buffer)->NumBases;
}
unsigned getStructNumFields() const {
assert(isStruct() && "Invalid accessor");
- return ((const StructData*)(const char*)Data.buffer)->NumFields;
+ return ((const StructData *)(const char *)&Data.buffer)->NumFields;
}
APValue &getStructBase(unsigned i) {
assert(isStruct() && "Invalid accessor");
- return ((StructData*)(char*)Data.buffer)->Elts[i];
+ return ((StructData *)(char *)&Data.buffer)->Elts[i];
}
APValue &getStructField(unsigned i) {
assert(isStruct() && "Invalid accessor");
- return ((StructData*)(char*)Data.buffer)->Elts[getStructNumBases() + i];
+ return ((StructData *)(char *)&Data.buffer)->Elts[getStructNumBases() + i];
}
const APValue &getStructBase(unsigned i) const {
return const_cast<APValue*>(this)->getStructBase(i);
@@ -473,11 +473,11 @@
const FieldDecl *getUnionField() const {
assert(isUnion() && "Invalid accessor");
- return ((const UnionData*)(const char*)Data.buffer)->Field;
+ return ((const UnionData *)(const char *)&Data.buffer)->Field;
}
APValue &getUnionValue() {
assert(isUnion() && "Invalid accessor");
- return *((UnionData*)(char*)Data.buffer)->Value;
+ return *((UnionData *)(char *)&Data.buffer)->Value;
}
const APValue &getUnionValue() const {
return const_cast<APValue*>(this)->getUnionValue();
@@ -489,45 +489,45 @@
const AddrLabelExpr* getAddrLabelDiffLHS() const {
assert(isAddrLabelDiff() && "Invalid accessor");
- return ((const AddrLabelDiffData*)(const char*)Data.buffer)->LHSExpr;
+ return ((const AddrLabelDiffData *)(const char *)&Data.buffer)->LHSExpr;
}
const AddrLabelExpr* getAddrLabelDiffRHS() const {
assert(isAddrLabelDiff() && "Invalid accessor");
- return ((const AddrLabelDiffData*)(const char*)Data.buffer)->RHSExpr;
+ return ((const AddrLabelDiffData *)(const char *)&Data.buffer)->RHSExpr;
}
void setInt(APSInt I) {
assert(isInt() && "Invalid accessor");
- *(APSInt *)(char *)Data.buffer = std::move(I);
+ *(APSInt *)(char *)&Data.buffer = std::move(I);
}
void setFloat(APFloat F) {
assert(isFloat() && "Invalid accessor");
- *(APFloat *)(char *)Data.buffer = std::move(F);
+ *(APFloat *)(char *)&Data.buffer = std::move(F);
}
void setFixedPoint(APFixedPoint FX) {
assert(isFixedPoint() && "Invalid accessor");
- *(APFixedPoint *)(char *)Data.buffer = std::move(FX);
+ *(APFixedPoint *)(char *)&Data.buffer = std::move(FX);
}
void setVector(const APValue *E, unsigned N) {
assert(isVector() && "Invalid accessor");
- ((Vec*)(char*)Data.buffer)->Elts = new APValue[N];
- ((Vec*)(char*)Data.buffer)->NumElts = N;
+ ((Vec *)(char *)&Data.buffer)->Elts = new APValue[N];
+ ((Vec *)(char *)&Data.buffer)->NumElts = N;
for (unsigned i = 0; i != N; ++i)
- ((Vec*)(char*)Data.buffer)->Elts[i] = E[i];
+ ((Vec *)(char *)&Data.buffer)->Elts[i] = E[i];
}
void setComplexInt(APSInt R, APSInt I) {
assert(R.getBitWidth() == I.getBitWidth() &&
"Invalid complex int (type mismatch).");
assert(isComplexInt() && "Invalid accessor");
- ((ComplexAPSInt *)(char *)Data.buffer)->Real = std::move(R);
- ((ComplexAPSInt *)(char *)Data.buffer)->Imag = std::move(I);
+ ((ComplexAPSInt *)(char *)&Data.buffer)->Real = std::move(R);
+ ((ComplexAPSInt *)(char *)&Data.buffer)->Imag = std::move(I);
}
void setComplexFloat(APFloat R, APFloat I) {
assert(&R.getSemantics() == &I.getSemantics() &&
"Invalid complex float (type mismatch).");
assert(isComplexFloat() && "Invalid accessor");
- ((ComplexAPFloat *)(char *)Data.buffer)->Real = std::move(R);
- ((ComplexAPFloat *)(char *)Data.buffer)->Imag = std::move(I);
+ ((ComplexAPFloat *)(char *)&Data.buffer)->Real = std::move(R);
+ ((ComplexAPFloat *)(char *)&Data.buffer)->Imag = std::move(I);
}
void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
bool IsNullPtr);
@@ -536,13 +536,13 @@
bool IsNullPtr);
void setUnion(const FieldDecl *Field, const APValue &Value) {
assert(isUnion() && "Invalid accessor");
- ((UnionData*)(char*)Data.buffer)->Field = Field;
- *((UnionData*)(char*)Data.buffer)->Value = Value;
+ ((UnionData *)(char *)&Data.buffer)->Field = Field;
+ *((UnionData *)(char *)&Data.buffer)->Value = Value;
}
void setAddrLabelDiff(const AddrLabelExpr* LHSExpr,
const AddrLabelExpr* RHSExpr) {
- ((AddrLabelDiffData*)(char*)Data.buffer)->LHSExpr = LHSExpr;
- ((AddrLabelDiffData*)(char*)Data.buffer)->RHSExpr = RHSExpr;
+ ((AddrLabelDiffData *)(char *)&Data.buffer)->LHSExpr = LHSExpr;
+ ((AddrLabelDiffData *)(char *)&Data.buffer)->RHSExpr = RHSExpr;
}
/// Assign by swapping from a copy of the RHS.
@@ -555,51 +555,51 @@
void DestroyDataAndMakeUninit();
void MakeInt() {
assert(isAbsent() && "Bad state change");
- new ((void*)Data.buffer) APSInt(1);
+ new ((void *)&Data.buffer) APSInt(1);
Kind = Int;
}
void MakeFloat() {
assert(isAbsent() && "Bad state change");
- new ((void*)(char*)Data.buffer) APFloat(0.0);
+ new ((void *)(char *)&Data.buffer) APFloat(0.0);
Kind = Float;
}
void MakeFixedPoint(APFixedPoint &&FX) {
assert(isAbsent() && "Bad state change");
- new ((void *)(char *)Data.buffer) APFixedPoint(std::move(FX));
+ new ((void *)(char *)&Data.buffer) APFixedPoint(std::move(FX));
Kind = FixedPoint;
}
void MakeVector() {
assert(isAbsent() && "Bad state change");
- new ((void*)(char*)Data.buffer) Vec();
+ new ((void *)(char *)&Data.buffer) Vec();
Kind = Vector;
}
void MakeComplexInt() {
assert(isAbsent() && "Bad state change");
- new ((void*)(char*)Data.buffer) ComplexAPSInt();
+ new ((void *)(char *)&Data.buffer) ComplexAPSInt();
Kind = ComplexInt;
}
void MakeComplexFloat() {
assert(isAbsent() && "Bad state change");
- new ((void*)(char*)Data.buffer) ComplexAPFloat();
+ new ((void *)(char *)&Data.buffer) ComplexAPFloat();
Kind = ComplexFloat;
}
void MakeLValue();
void MakeArray(unsigned InitElts, unsigned Size);
void MakeStruct(unsigned B, unsigned M) {
assert(isAbsent() && "Bad state change");
- new ((void*)(char*)Data.buffer) StructData(B, M);
+ new ((void *)(char *)&Data.buffer) StructData(B, M);
Kind = Struct;
}
void MakeUnion() {
assert(isAbsent() && "Bad state change");
- new ((void*)(char*)Data.buffer) UnionData();
+ new ((void *)(char *)&Data.buffer) UnionData();
Kind = Union;
}
void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
ArrayRef<const CXXRecordDecl*> Path);
void MakeAddrLabelDiff() {
assert(isAbsent() && "Bad state change");
- new ((void*)(char*)Data.buffer) AddrLabelDiffData();
+ new ((void *)(char *)&Data.buffer) AddrLabelDiffData();
Kind = AddrLabelDiff;
}
};
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits