diff --git a/clang/include/clang/AST/APValue.h b/clang/include/clang/AST/APValue.h --- a/clang/include/clang/AST/APValue.h +++ b/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(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(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(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(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(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(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(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(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(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(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(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(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 Path); void MakeAddrLabelDiff() { assert(isAbsent() && "Bad state change"); - new ((void*)(char*)Data.buffer) AddrLabelDiffData(); + new ((void *)(char *)&Data.buffer) AddrLabelDiffData(); Kind = AddrLabelDiff; } }; diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h --- a/clang/include/clang/AST/ASTContext.h +++ b/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 A) : IsSingleNode(false) { - new (Storage.buffer) ArrayRef(A); + new (&Storage.buffer) ArrayRef(A); } const ast_type_traits::DynTypedNode *begin() const { if (!IsSingleNode) - return reinterpret_cast *>(Storage.buffer) + return reinterpret_cast *>(&Storage.buffer) ->begin(); - return reinterpret_cast(Storage.buffer); + return reinterpret_cast(&Storage.buffer); } const ast_type_traits::DynTypedNode *end() const { if (!IsSingleNode) - return reinterpret_cast *>(Storage.buffer) + return reinterpret_cast *>(&Storage.buffer) ->end(); - return reinterpret_cast(Storage.buffer) + 1; + return reinterpret_cast(&Storage.buffer) + 1; } size_t size() const { return end() - begin(); } diff --git a/clang/include/clang/AST/ASTTypeTraits.h b/clang/include/clang/AST/ASTTypeTraits.h --- a/clang/include/clang/AST/ASTTypeTraits.h +++ b/clang/include/clang/AST/ASTTypeTraits.h @@ -249,7 +249,7 @@ /// use the pointer outside the scope of the DynTypedNode. template const T *get() const { - return BaseConverter::get(NodeKind, Storage.buffer); + return BaseConverter::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 const T &getUnchecked() const { - return BaseConverter::getUnchecked(NodeKind, Storage.buffer); + return BaseConverter::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(Storage.buffer) + ? *reinterpret_cast(&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(); - 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(); - new (Result.Storage.buffer) T(Node); + new (&Result.Storage.buffer) T(Node); return Result; } }; diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -2619,9 +2619,9 @@ /// + sizeof(Stmt *) bytes of storage, aligned to alignof(CallExpr): /// /// \code{.cpp} - /// llvm::AlignedCharArray Buffer; - /// CallExpr *TheCall = CallExpr::CreateTemporary(Buffer.buffer, etc); + /// std::aligned_storage::type Buffer; + /// CallExpr *TheCall = CallExpr::CreateTemporary(Buffer, etc); /// \endcode static CallExpr *CreateTemporary(void *Mem, Expr *Fn, QualType Ty, ExprValueKind VK, SourceLocation RParenLoc, diff --git a/clang/include/clang/Sema/Overload.h b/clang/include/clang/Sema/Overload.h --- a/clang/include/clang/Sema/Overload.h +++ b/clang/include/clang/Sema/Overload.h @@ -881,7 +881,7 @@ constexpr static unsigned NumInlineBytes = 24 * sizeof(ImplicitConversionSequence); unsigned NumInlineBytesUsed = 0; - llvm::AlignedCharArray InlineSpace; + std::aligned_storage::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(N); - char *FreeSpaceStart = InlineSpace.buffer + NumInlineBytesUsed; + char *FreeSpaceStart = + reinterpret_cast(&InlineSpace) + NumInlineBytesUsed; assert(uintptr_t(FreeSpaceStart) % alignof(void *) == 0 && "Misaligned storage!"); diff --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp --- a/clang/lib/AST/APValue.cpp +++ b/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(Data.buffer)->hasPathPtr(); + return reinterpret_cast(&Data.buffer)->hasPathPtr(); case MemberPointer: - return reinterpret_cast(Data.buffer) + return reinterpret_cast(&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::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 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 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 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); diff --git a/clang/lib/CodeGen/CGCleanup.cpp b/clang/lib/CodeGen/CGCleanup.cpp --- a/clang/lib/CodeGen/CGCleanup.cpp +++ b/clang/lib/CodeGen/CGCleanup.cpp @@ -740,14 +740,16 @@ // here. Unfortunately, if you ask for a SmallVector, the // alignment isn't sufficient. auto *CleanupSource = reinterpret_cast(Scope.getCleanupBuffer()); - llvm::AlignedCharArray CleanupBufferStack; + std::aligned_storage<8 * sizeof(void *), + EHScopeStack::ScopeStackAlignment>::type + CleanupBufferStack; std::unique_ptr CleanupBufferHeap; size_t CleanupSize = Scope.getCleanupSize(); EHScopeStack::Cleanup *Fn; if (CleanupSize <= sizeof(CleanupBufferStack)) { - memcpy(CleanupBufferStack.buffer, CleanupSource, CleanupSize); - Fn = reinterpret_cast(CleanupBufferStack.buffer); + memcpy(&CleanupBufferStack, CleanupSource, CleanupSize); + Fn = reinterpret_cast(&CleanupBufferStack); } else { CleanupBufferHeap.reset(new char[CleanupSize]); memcpy(CleanupBufferHeap.get(), CleanupSource, CleanupSize); diff --git a/clang/lib/DirectoryWatcher/linux/DirectoryWatcher-linux.cpp b/clang/lib/DirectoryWatcher/linux/DirectoryWatcher-linux.cpp --- a/clang/lib/DirectoryWatcher/linux/DirectoryWatcher-linux.cpp +++ b/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>(); - char *const Buf = ManagedBuffer->buffer; + auto ManagedBuffer = llvm::make_unique::type>(); + char *const Buf = ManagedBuffer.get(); const int EpollFD = epoll_create1(EPOLL_CLOEXEC); if (EpollFD == -1) { @@ -350,4 +349,4 @@ return llvm::make_unique( Path, Receiver, WaitForInitialSync, InotifyFD, InotifyWD, std::move(*InotifyPollingStopper)); -} \ No newline at end of file +} diff --git a/clang/lib/Frontend/PrecompiledPreamble.cpp b/clang/lib/Frontend/PrecompiledPreamble.cpp --- a/clang/lib/Frontend/PrecompiledPreamble.cpp +++ b/clang/lib/Frontend/PrecompiledPreamble.cpp @@ -637,7 +637,7 @@ PrecompiledPreamble::TempPCHFile &PrecompiledPreamble::PCHStorage::asFile() { assert(getKind() == Kind::TempFile); - return *reinterpret_cast(Storage.buffer); + return *reinterpret_cast(&Storage.buffer); } const PrecompiledPreamble::TempPCHFile & @@ -648,7 +648,7 @@ PrecompiledPreamble::InMemoryPreamble & PrecompiledPreamble::PCHStorage::asMemory() { assert(getKind() == Kind::InMemory); - return *reinterpret_cast(Storage.buffer); + return *reinterpret_cast(&Storage.buffer); } const PrecompiledPreamble::InMemoryPreamble & diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -7052,10 +7052,10 @@ // allocator). QualType CallResultType = ConversionType.getNonLValueExprType(Context); - llvm::AlignedCharArray - Buffer; + std::aligned_storage::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, diff --git a/clang/lib/Sema/TypeLocBuilder.h b/clang/lib/Sema/TypeLocBuilder.h --- a/clang/lib/Sema/TypeLocBuilder.h +++ b/clang/lib/Sema/TypeLocBuilder.h @@ -39,19 +39,18 @@ /// The inline buffer. enum { BufferMaxAlignment = alignof(void *) }; - llvm::AlignedCharArray InlineBuffer; + std::aligned_storage::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(&InlineBuffer)), + Capacity(InlineCapacity), Index(InlineCapacity), NumBytesAtAlign4(0), + NumBytesAtAlign8(0) {} + + ~TypeLocBuilder() { + if (Buffer != reinterpret_cast(&InlineBuffer)) + delete[] Buffer; } /// Ensures that this buffer has at least as much capacity as described. diff --git a/clang/lib/Sema/TypeLocBuilder.cpp b/clang/lib/Sema/TypeLocBuilder.cpp --- a/clang/lib/Sema/TypeLocBuilder.cpp +++ b/clang/lib/Sema/TypeLocBuilder.cpp @@ -51,7 +51,7 @@ &Buffer[Index], Capacity - Index); - if (Buffer != InlineBuffer.buffer) + if (Buffer != reinterpret_cast(&InlineBuffer)) delete[] Buffer; Buffer = NewBuffer; diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h --- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h +++ b/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 arm_neon_state64_t diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp --- a/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp +++ b/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; diff --git a/llvm/include/llvm/ADT/DenseMap.h b/llvm/include/llvm/ADT/DenseMap.h --- a/llvm/include/llvm/ADT/DenseMap.h +++ b/llvm/include/llvm/ADT/DenseMap.h @@ -1037,7 +1037,7 @@ // First move the inline buckets into a temporary storage. AlignedCharArrayUnion TmpStorage; - BucketT *TmpBegin = reinterpret_cast(TmpStorage.buffer); + BucketT *TmpBegin = reinterpret_cast(&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(storage.buffer); + return reinterpret_cast(&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(storage.buffer); + return reinterpret_cast(&storage.buffer); } LargeRep *getLargeRep() { diff --git a/llvm/include/llvm/ADT/IntervalMap.h b/llvm/include/llvm/ADT/IntervalMap.h --- a/llvm/include/llvm/ADT/IntervalMap.h +++ b/llvm/include/llvm/ADT/IntervalMap.h @@ -981,7 +981,8 @@ /// Represent data as a node type without breaking aliasing rules. template T &dataAs() const { - return *bit_cast(const_cast(data.buffer)); + return *bit_cast( + const_cast(reinterpret_cast(&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(); } diff --git a/llvm/include/llvm/CodeGen/DIE.h b/llvm/include/llvm/CodeGen/DIE.h --- a/llvm/include/llvm/CodeGen/DIE.h +++ b/llvm/include/llvm/CodeGen/DIE.h @@ -382,12 +382,12 @@ 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.buffer)) T(V); } - template T *get() { return reinterpret_cast(Val.buffer); } + template T *get() { return reinterpret_cast(&Val.buffer); } template const T *get() const { - return reinterpret_cast(Val.buffer); + return reinterpret_cast(&Val.buffer); } template void destruct() { get()->~T(); } diff --git a/llvm/include/llvm/Support/AlignOf.h b/llvm/include/llvm/Support/AlignOf.h --- a/llvm/include/llvm/Support/AlignOf.h +++ b/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 +#include 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 -struct AlignedCharArray { - alignas(Alignment) char buffer[Size]; -}; - -#else // _MSC_VER - -/// Create a type with an aligned char buffer. -template -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 -struct AlignedCharArray<1, Size> { - union { - char aligned; - char buffer[Size]; - }; -}; - -template -struct AlignedCharArray<2, Size> { - union { - short aligned; - char buffer[Size]; - }; -}; - -template -struct AlignedCharArray<4, Size> { - union { - int aligned; - char buffer[Size]; - }; -}; +namespace detail { +template class AlignerImpl { + T t; + AlignerImpl rest; -template -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 \ - struct AlignedCharArray { \ - __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 -class AlignerImpl { - T1 t1; T2 t2; T3 t3; T4 t4; T5 t5; T6 t6; T7 t7; T8 t8; T9 t9; T10 t10; +template class AlignerImpl { + T t; AlignerImpl() = delete; }; -template -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 union SizerImpl { + char arr[sizeof(T)]; + SizerImpl rest; }; + +template union SizerImpl { 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 -struct AlignedCharArrayUnion : llvm::AlignedCharArray< - alignof(llvm::detail::AlignerImpl), - sizeof(::llvm::detail::SizerImpl)> { +/// 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 struct AlignedCharArrayUnion { + typename std::aligned_storage< + sizeof(llvm::detail::SizerImpl), + alignof(::llvm::detail::AlignerImpl)>::type buffer; }; } // end namespace llvm diff --git a/llvm/include/llvm/Support/Endian.h b/llvm/include/llvm/Support/Endian.h --- a/llvm/include/llvm/Support/Endian.h +++ b/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( - (const void*)Value.buffer); + return endian::read((const void *)&Value); } void operator=(value_type newValue) { - endian::write( - (void*)Value.buffer, newValue); + endian::write((void *)&Value, newValue); } packed_endian_specific_integral &operator+=(value_type newValue) { @@ -246,8 +244,9 @@ } private: - AlignedCharArray::value, - sizeof(value_type)> Value; + typename std::aligned_storage< + sizeof(value_type), PickAlignment::value>::type + Value; public: struct ref { diff --git a/llvm/include/llvm/Support/Error.h b/llvm/include/llvm/Support/Error.h --- a/llvm/include/llvm/Support/Error.h +++ b/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(TStorage.buffer); + return reinterpret_cast(&TStorage.buffer); } const storage_type *getStorage() const { assert(!HasError && "Cannot get value when an error exists!"); - return reinterpret_cast(TStorage.buffer); + return reinterpret_cast(&TStorage.buffer); } error_type *getErrorStorage() { assert(HasError && "Cannot get error when a value exists!"); - return reinterpret_cast(ErrorStorage.buffer); + return reinterpret_cast(&ErrorStorage.buffer); } const error_type *getErrorStorage() const { assert(HasError && "Cannot get error when a value exists!"); - return reinterpret_cast(ErrorStorage.buffer); + return reinterpret_cast(&ErrorStorage.buffer); } // Used by ExpectedAsOutParameter to reset the checked flag. diff --git a/llvm/include/llvm/Support/ErrorOr.h b/llvm/include/llvm/Support/ErrorOr.h --- a/llvm/include/llvm/Support/ErrorOr.h +++ b/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(TStorage.buffer); + return reinterpret_cast(&TStorage.buffer); } const storage_type *getStorage() const { assert(!HasError && "Cannot get value when an error exists!"); - return reinterpret_cast(TStorage.buffer); + return reinterpret_cast(&TStorage.buffer); } std::error_code *getErrorStorage() { assert(HasError && "Cannot get error when a value exists!"); - return reinterpret_cast(ErrorStorage.buffer); + return reinterpret_cast(&ErrorStorage.buffer); } const std::error_code *getErrorStorage() const { diff --git a/llvm/include/llvm/Support/JSON.h b/llvm/include/llvm/Support/JSON.h --- a/llvm/include/llvm/Support/JSON.h +++ b/llvm/include/llvm/Support/JSON.h @@ -451,12 +451,12 @@ friend class Object; template void create(U &&... V) { - new (reinterpret_cast(Union.buffer)) T(std::forward(V)...); + new (reinterpret_cast(&Union.buffer)) 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.buffer); return *static_cast(Storage); } diff --git a/llvm/include/llvm/Support/TrailingObjects.h b/llvm/include/llvm/Support/TrailingObjects.h --- a/llvm/include/llvm/Support/TrailingObjects.h +++ b/llvm/include/llvm/Support/TrailingObjects.h @@ -369,7 +369,7 @@ template struct FixedSizeStorage { template struct with_counts { enum { Size = totalSizeToAlloc(Counts...) }; - typedef llvm::AlignedCharArray type; + using type = typename std::aligned_storage::type; }; }; diff --git a/llvm/lib/Support/JSON.cpp b/llvm/lib/Support/JSON.cpp --- a/llvm/lib/Support/JSON.cpp +++ b/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(M.as()); @@ -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(M.as()); diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/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(&FpValBuf.buffer[0]); } + APFloat *getFpValPtr() { + return reinterpret_cast(&FpValBuf.buffer); + } - const APFloat *getFpValPtr() const - { return reinterpret_cast(&FpValBuf.buffer[0]); } + const APFloat *getFpValPtr() const { + return reinterpret_cast(&FpValBuf.buffer); + } const APFloat &getFpVal() const { assert(IsFp && BufHasFpVal && "Incorret state"); diff --git a/llvm/unittests/Support/AlignOfTest.cpp b/llvm/unittests/Support/AlignOfTest.cpp --- a/llvm/unittests/Support/AlignOfTest.cpp +++ b/llvm/unittests/Support/AlignOfTest.cpp @@ -233,16 +233,5 @@ #ifndef _MSC_VER EXPECT_EQ(sizeof(V8), sizeof(AlignedCharArrayUnion)); #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