Hi Richard, I believe that your commit r198845 has broken the following buildbot:
http://lab.llvm.org:8013/builders/clang-x86_64-darwin11-nobootstrap-RAincremental/builds/11015 Would you please fix this? Thanks, Duncan On 2014 Jan 8, at 19:29, Richard Smith <[email protected]> wrote: > Author: rsmith > Date: Wed Jan 8 21:29:54 2014 > New Revision: 198845 > > URL: http://llvm.org/viewvc/llvm-project?rev=198845&view=rev > Log: > PR18427: Use an appropriately-aligned buffer in APValue, to avoid a crash on > SPARC, where uint64_t apparently requires higher alignment than void*. > > Modified: > cfe/trunk/include/clang/AST/APValue.h > cfe/trunk/lib/AST/APValue.cpp > > Modified: cfe/trunk/include/clang/AST/APValue.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/APValue.h?rev=198845&r1=198844&r2=198845&view=diff > ============================================================================== > --- cfe/trunk/include/clang/AST/APValue.h (original) > +++ cfe/trunk/include/clang/AST/APValue.h Wed Jan 8 21:29:54 2014 > @@ -108,15 +108,10 @@ private: > }; > struct MemberPointerData; > > - enum { > - MaxSize = (sizeof(ComplexAPSInt) > sizeof(ComplexAPFloat) ? > - sizeof(ComplexAPSInt) : sizeof(ComplexAPFloat)) > - }; > - > - union { > - void *Aligner; > - char Data[MaxSize]; > - }; > + // We ensure elsewhere that Data is big enough for LV and > MemberPointerData. > + llvm::AlignedCharArrayUnion<void *, APSInt, APFloat, ComplexAPSInt, > + ComplexAPFloat, Vec, Arr, StructData, > UnionData, > + AddrLabelDiffData> Data; > > public: > APValue() : Kind(Uninitialized) {} > @@ -200,7 +195,7 @@ public: > > APSInt &getInt() { > assert(isInt() && "Invalid accessor"); > - return *(APSInt*)(char*)Data; > + return *(APSInt*)(char*)Data.buffer; > } > const APSInt &getInt() const { > return const_cast<APValue*>(this)->getInt(); > @@ -208,7 +203,7 @@ public: > > APFloat &getFloat() { > assert(isFloat() && "Invalid accessor"); > - return *(APFloat*)(char*)Data; > + return *(APFloat*)(char*)Data.buffer; > } > const APFloat &getFloat() const { > return const_cast<APValue*>(this)->getFloat(); > @@ -216,7 +211,7 @@ public: > > APSInt &getComplexIntReal() { > assert(isComplexInt() && "Invalid accessor"); > - return ((ComplexAPSInt*)(char*)Data)->Real; > + return ((ComplexAPSInt*)(char*)Data.buffer)->Real; > } > const APSInt &getComplexIntReal() const { > return const_cast<APValue*>(this)->getComplexIntReal(); > @@ -224,7 +219,7 @@ public: > > APSInt &getComplexIntImag() { > assert(isComplexInt() && "Invalid accessor"); > - return ((ComplexAPSInt*)(char*)Data)->Imag; > + return ((ComplexAPSInt*)(char*)Data.buffer)->Imag; > } > const APSInt &getComplexIntImag() const { > return const_cast<APValue*>(this)->getComplexIntImag(); > @@ -232,7 +227,7 @@ public: > > APFloat &getComplexFloatReal() { > assert(isComplexFloat() && "Invalid accessor"); > - return ((ComplexAPFloat*)(char*)Data)->Real; > + return ((ComplexAPFloat*)(char*)Data.buffer)->Real; > } > const APFloat &getComplexFloatReal() const { > return const_cast<APValue*>(this)->getComplexFloatReal(); > @@ -240,7 +235,7 @@ public: > > APFloat &getComplexFloatImag() { > assert(isComplexFloat() && "Invalid accessor"); > - return ((ComplexAPFloat*)(char*)Data)->Imag; > + return ((ComplexAPFloat*)(char*)Data.buffer)->Imag; > } > const APFloat &getComplexFloatImag() const { > return const_cast<APValue*>(this)->getComplexFloatImag(); > @@ -259,20 +254,20 @@ public: > APValue &getVectorElt(unsigned I) { > assert(isVector() && "Invalid accessor"); > assert(I < getVectorLength() && "Index out of range"); > - return ((Vec*)(char*)Data)->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)->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)->Elts[I]; > + return ((Arr*)(char*)Data.buffer)->Elts[I]; > } > const APValue &getArrayInitializedElt(unsigned I) const { > return const_cast<APValue*>(this)->getArrayInitializedElt(I); > @@ -283,35 +278,35 @@ public: > APValue &getArrayFiller() { > assert(isArray() && "Invalid accessor"); > assert(hasArrayFiller() && "No array filler"); > - return ((Arr*)(char*)Data)->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)->NumElts; > + return ((const Arr*)(const void *)Data.buffer)->NumElts; > } > unsigned getArraySize() const { > assert(isArray() && "Invalid accessor"); > - return ((const Arr*)(const void *)Data)->ArrSize; > + return ((const Arr*)(const void *)Data.buffer)->ArrSize; > } > > unsigned getStructNumBases() const { > assert(isStruct() && "Invalid accessor"); > - return ((const StructData*)(const char*)Data)->NumBases; > + return ((const StructData*)(const char*)Data.buffer)->NumBases; > } > unsigned getStructNumFields() const { > assert(isStruct() && "Invalid accessor"); > - return ((const StructData*)(const char*)Data)->NumFields; > + return ((const StructData*)(const char*)Data.buffer)->NumFields; > } > APValue &getStructBase(unsigned i) { > assert(isStruct() && "Invalid accessor"); > - return ((StructData*)(char*)Data)->Elts[i]; > + return ((StructData*)(char*)Data.buffer)->Elts[i]; > } > APValue &getStructField(unsigned i) { > assert(isStruct() && "Invalid accessor"); > - return ((StructData*)(char*)Data)->Elts[getStructNumBases() + i]; > + return ((StructData*)(char*)Data.buffer)->Elts[getStructNumBases() + i]; > } > const APValue &getStructBase(unsigned i) const { > return const_cast<APValue*>(this)->getStructBase(i); > @@ -322,11 +317,11 @@ public: > > const FieldDecl *getUnionField() const { > assert(isUnion() && "Invalid accessor"); > - return ((const UnionData*)(const char*)Data)->Field; > + return ((const UnionData*)(const char*)Data.buffer)->Field; > } > APValue &getUnionValue() { > assert(isUnion() && "Invalid accessor"); > - return *((UnionData*)(char*)Data)->Value; > + return *((UnionData*)(char*)Data.buffer)->Value; > } > const APValue &getUnionValue() const { > return const_cast<APValue*>(this)->getUnionValue(); > @@ -338,41 +333,41 @@ public: > > const AddrLabelExpr* getAddrLabelDiffLHS() const { > assert(isAddrLabelDiff() && "Invalid accessor"); > - return ((const AddrLabelDiffData*)(const char*)Data)->LHSExpr; > + return ((const AddrLabelDiffData*)(const char*)Data.buffer)->LHSExpr; > } > const AddrLabelExpr* getAddrLabelDiffRHS() const { > assert(isAddrLabelDiff() && "Invalid accessor"); > - return ((const AddrLabelDiffData*)(const char*)Data)->RHSExpr; > + return ((const AddrLabelDiffData*)(const char*)Data.buffer)->RHSExpr; > } > > void setInt(const APSInt &I) { > assert(isInt() && "Invalid accessor"); > - *(APSInt*)(char*)Data = I; > + *(APSInt*)(char*)Data.buffer = I; > } > void setFloat(const APFloat &F) { > assert(isFloat() && "Invalid accessor"); > - *(APFloat*)(char*)Data = F; > + *(APFloat*)(char*)Data.buffer = F; > } > void setVector(const APValue *E, unsigned N) { > assert(isVector() && "Invalid accessor"); > - ((Vec*)(char*)Data)->Elts = new APValue[N]; > - ((Vec*)(char*)Data)->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)->Elts[i] = E[i]; > + ((Vec*)(char*)Data.buffer)->Elts[i] = E[i]; > } > void setComplexInt(const APSInt &R, const APSInt &I) { > assert(R.getBitWidth() == I.getBitWidth() && > "Invalid complex int (type mismatch)."); > assert(isComplexInt() && "Invalid accessor"); > - ((ComplexAPSInt*)(char*)Data)->Real = R; > - ((ComplexAPSInt*)(char*)Data)->Imag = I; > + ((ComplexAPSInt*)(char*)Data.buffer)->Real = R; > + ((ComplexAPSInt*)(char*)Data.buffer)->Imag = I; > } > void setComplexFloat(const APFloat &R, const APFloat &I) { > assert(&R.getSemantics() == &I.getSemantics() && > "Invalid complex float (type mismatch)."); > assert(isComplexFloat() && "Invalid accessor"); > - ((ComplexAPFloat*)(char*)Data)->Real = R; > - ((ComplexAPFloat*)(char*)Data)->Imag = I; > + ((ComplexAPFloat*)(char*)Data.buffer)->Real = R; > + ((ComplexAPFloat*)(char*)Data.buffer)->Imag = I; > } > void setLValue(LValueBase B, const CharUnits &O, NoLValuePath, > unsigned CallIndex); > @@ -381,13 +376,13 @@ public: > unsigned CallIndex); > void setUnion(const FieldDecl *Field, const APValue &Value) { > assert(isUnion() && "Invalid accessor"); > - ((UnionData*)(char*)Data)->Field = Field; > - *((UnionData*)(char*)Data)->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)->LHSExpr = LHSExpr; > - ((AddrLabelDiffData*)(char*)Data)->RHSExpr = RHSExpr; > + ((AddrLabelDiffData*)(char*)Data.buffer)->LHSExpr = LHSExpr; > + ((AddrLabelDiffData*)(char*)Data.buffer)->RHSExpr = RHSExpr; > } > > /// Assign by swapping from a copy of the RHS. > @@ -404,46 +399,46 @@ private: > } > void MakeInt() { > assert(isUninit() && "Bad state change"); > - new ((void*)Data) APSInt(1); > + new ((void*)Data.buffer) APSInt(1); > Kind = Int; > } > void MakeFloat() { > assert(isUninit() && "Bad state change"); > - new ((void*)(char*)Data) APFloat(0.0); > + new ((void*)(char*)Data.buffer) APFloat(0.0); > Kind = Float; > } > void MakeVector() { > assert(isUninit() && "Bad state change"); > - new ((void*)(char*)Data) Vec(); > + new ((void*)(char*)Data.buffer) Vec(); > Kind = Vector; > } > void MakeComplexInt() { > assert(isUninit() && "Bad state change"); > - new ((void*)(char*)Data) ComplexAPSInt(); > + new ((void*)(char*)Data.buffer) ComplexAPSInt(); > Kind = ComplexInt; > } > void MakeComplexFloat() { > assert(isUninit() && "Bad state change"); > - new ((void*)(char*)Data) ComplexAPFloat(); > + new ((void*)(char*)Data.buffer) ComplexAPFloat(); > Kind = ComplexFloat; > } > void MakeLValue(); > void MakeArray(unsigned InitElts, unsigned Size); > void MakeStruct(unsigned B, unsigned M) { > assert(isUninit() && "Bad state change"); > - new ((void*)(char*)Data) StructData(B, M); > + new ((void*)(char*)Data.buffer) StructData(B, M); > Kind = Struct; > } > void MakeUnion() { > assert(isUninit() && "Bad state change"); > - new ((void*)(char*)Data) UnionData(); > + new ((void*)(char*)Data.buffer) UnionData(); > Kind = Union; > } > void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember, > ArrayRef<const CXXRecordDecl*> Path); > void MakeAddrLabelDiff() { > assert(isUninit() && "Bad state change"); > - new ((void*)(char*)Data) AddrLabelDiffData(); > + new ((void*)(char*)Data.buffer) AddrLabelDiffData(); > Kind = AddrLabelDiff; > } > }; > > Modified: cfe/trunk/lib/AST/APValue.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/APValue.cpp?rev=198845&r1=198844&r2=198845&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/APValue.cpp (original) > +++ cfe/trunk/lib/AST/APValue.cpp Wed Jan 8 21:29:54 2014 > @@ -34,7 +34,7 @@ namespace { > > struct APValue::LV : LVBase { > static const unsigned InlinePathSpace = > - (MaxSize - sizeof(LVBase)) / sizeof(LValuePathEntry); > + (sizeof(Data.buffer) - sizeof(LVBase)) / sizeof(LValuePathEntry); > > /// Path - The sequence of base classes, fields and array indices to follow > to > /// walk from Base to the subobject. When performing GCC-style folding, > there > @@ -75,7 +75,8 @@ namespace { > > struct APValue::MemberPointerData : MemberPointerBase { > static const unsigned InlinePathSpace = > - (MaxSize - sizeof(MemberPointerBase)) / sizeof(const CXXRecordDecl*); > + (sizeof(Data.buffer) - sizeof(MemberPointerBase)) / > + sizeof(const CXXRecordDecl *); > typedef const CXXRecordDecl *PathElem; > union { > PathElem Path[InlinePathSpace]; > @@ -136,7 +137,7 @@ APValue::APValue(const APValue &RHS) : K > break; > case Vector: > MakeVector(); > - setVector(((const Vec *)(const char *)RHS.Data)->Elts, > + setVector(((const Vec *)(const char *)RHS.Data.buffer)->Elts, > RHS.getVectorLength()); > break; > case ComplexInt: > @@ -188,27 +189,27 @@ APValue::APValue(const APValue &RHS) : K > > void APValue::DestroyDataAndMakeUninit() { > if (Kind == Int) > - ((APSInt*)(char*)Data)->~APSInt(); > + ((APSInt*)(char*)Data.buffer)->~APSInt(); > else if (Kind == Float) > - ((APFloat*)(char*)Data)->~APFloat(); > + ((APFloat*)(char*)Data.buffer)->~APFloat(); > else if (Kind == Vector) > - ((Vec*)(char*)Data)->~Vec(); > + ((Vec*)(char*)Data.buffer)->~Vec(); > else if (Kind == ComplexInt) > - ((ComplexAPSInt*)(char*)Data)->~ComplexAPSInt(); > + ((ComplexAPSInt*)(char*)Data.buffer)->~ComplexAPSInt(); > else if (Kind == ComplexFloat) > - ((ComplexAPFloat*)(char*)Data)->~ComplexAPFloat(); > + ((ComplexAPFloat*)(char*)Data.buffer)->~ComplexAPFloat(); > else if (Kind == LValue) > - ((LV*)(char*)Data)->~LV(); > + ((LV*)(char*)Data.buffer)->~LV(); > else if (Kind == Array) > - ((Arr*)(char*)Data)->~Arr(); > + ((Arr*)(char*)Data.buffer)->~Arr(); > else if (Kind == Struct) > - ((StructData*)(char*)Data)->~StructData(); > + ((StructData*)(char*)Data.buffer)->~StructData(); > else if (Kind == Union) > - ((UnionData*)(char*)Data)->~UnionData(); > + ((UnionData*)(char*)Data.buffer)->~UnionData(); > else if (Kind == MemberPointer) > - ((MemberPointerData*)(char*)Data)->~MemberPointerData(); > + ((MemberPointerData*)(char*)Data.buffer)->~MemberPointerData(); > else if (Kind == AddrLabelDiff) > - ((AddrLabelDiffData*)(char*)Data)->~AddrLabelDiffData(); > + ((AddrLabelDiffData*)(char*)Data.buffer)->~AddrLabelDiffData(); > Kind = Uninitialized; > } > > @@ -239,19 +240,21 @@ bool APValue::needsCleanup() const { > "same size."); > return getComplexIntReal().needsCleanup(); > case LValue: > - return reinterpret_cast<const LV *>(Data)->hasPathPtr(); > + return reinterpret_cast<const LV *>(Data.buffer)->hasPathPtr(); > case MemberPointer: > - return reinterpret_cast<const MemberPointerData *>(Data)->hasPathPtr(); > + return reinterpret_cast<const MemberPointerData *>(Data.buffer) > + ->hasPathPtr(); > } > llvm_unreachable("Unknown APValue kind!"); > } > > void APValue::swap(APValue &RHS) { > std::swap(Kind, RHS.Kind); > + const unsigned MaxSize = sizeof(Data.buffer); > char TmpData[MaxSize]; > - memcpy(TmpData, Data, MaxSize); > - memcpy(Data, RHS.Data, MaxSize); > - memcpy(RHS.Data, TmpData, MaxSize); > + memcpy(TmpData, Data.buffer, MaxSize); > + memcpy(Data.buffer, RHS.Data.buffer, MaxSize); > + memcpy(RHS.Data.buffer, TmpData, MaxSize); > } > > void APValue::dump() const { > @@ -546,39 +549,39 @@ std::string APValue::getAsString(ASTCont > > const APValue::LValueBase APValue::getLValueBase() const { > assert(isLValue() && "Invalid accessor"); > - return ((const LV*)(const void*)Data)->BaseAndIsOnePastTheEnd.getPointer(); > + return ((const LV*)(const > void*)Data.buffer)->BaseAndIsOnePastTheEnd.getPointer(); > } > > bool APValue::isLValueOnePastTheEnd() const { > assert(isLValue() && "Invalid accessor"); > - return ((const LV*)(const void*)Data)->BaseAndIsOnePastTheEnd.getInt(); > + return ((const LV*)(const > void*)Data.buffer)->BaseAndIsOnePastTheEnd.getInt(); > } > > CharUnits &APValue::getLValueOffset() { > assert(isLValue() && "Invalid accessor"); > - return ((LV*)(void*)Data)->Offset; > + return ((LV*)(void*)Data.buffer)->Offset; > } > > bool APValue::hasLValuePath() const { > assert(isLValue() && "Invalid accessor"); > - return ((const LV*)(const char*)Data)->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); > + const LV &LVal = *((const LV*)(const char*)Data.buffer); > return ArrayRef<LValuePathEntry>(LVal.getPath(), LVal.PathLength); > } > > unsigned APValue::getLValueCallIndex() const { > assert(isLValue() && "Invalid accessor"); > - return ((const LV*)(const char*)Data)->CallIndex; > + return ((const LV*)(const char*)Data.buffer)->CallIndex; > } > > void APValue::setLValue(LValueBase B, const CharUnits &O, NoLValuePath, > unsigned CallIndex) { > assert(isLValue() && "Invalid accessor"); > - LV &LVal = *((LV*)(char*)Data); > + LV &LVal = *((LV*)(char*)Data.buffer); > LVal.BaseAndIsOnePastTheEnd.setPointer(B); > LVal.BaseAndIsOnePastTheEnd.setInt(false); > LVal.Offset = O; > @@ -590,7 +593,7 @@ void APValue::setLValue(LValueBase B, co > ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd, > unsigned CallIndex) { > assert(isLValue() && "Invalid accessor"); > - LV &LVal = *((LV*)(char*)Data); > + LV &LVal = *((LV*)(char*)Data.buffer); > LVal.BaseAndIsOnePastTheEnd.setPointer(B); > LVal.BaseAndIsOnePastTheEnd.setInt(IsOnePastTheEnd); > LVal.Offset = O; > @@ -601,39 +604,42 @@ void APValue::setLValue(LValueBase B, co > > const ValueDecl *APValue::getMemberPointerDecl() const { > assert(isMemberPointer() && "Invalid accessor"); > - const MemberPointerData &MPD = *((const MemberPointerData*)(const > char*)Data); > + const MemberPointerData &MPD = > + *((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); > + const MemberPointerData &MPD = > + *((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); > + const MemberPointerData &MPD = > + *((const MemberPointerData *)(const char *)Data.buffer); > return ArrayRef<const CXXRecordDecl*>(MPD.getPath(), MPD.PathLength); > } > > void APValue::MakeLValue() { > assert(isUninit() && "Bad state change"); > - assert(sizeof(LV) <= MaxSize && "LV too big"); > - new ((void*)(char*)Data) LV(); > + assert(sizeof(LV) <= sizeof(Data.buffer) && "LV too big"); > + new ((void*)(char*)Data.buffer) LV(); > Kind = LValue; > } > > void APValue::MakeArray(unsigned InitElts, unsigned Size) { > assert(isUninit() && "Bad state change"); > - new ((void*)(char*)Data) 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(isUninit() && "Bad state change"); > - MemberPointerData *MPD = new ((void*)(char*)Data) MemberPointerData; > + MemberPointerData *MPD = new ((void*)(char*)Data.buffer) MemberPointerData; > Kind = MemberPointer; > MPD->MemberAndIsDerivedMember.setPointer(Member); > MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember); > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
