diff options
author | Momchil Velikov <momchil.velikov@arm.com> | 2018-07-30 17:48:23 +0000 |
---|---|---|
committer | Momchil Velikov <momchil.velikov@arm.com> | 2018-07-30 17:48:23 +0000 |
commit | 20208cc046c206a1436edb714e94bd52a0bc8572 (patch) | |
tree | 24548919809d313e32c81ace99e7da457dbf1d1b /clang/lib/AST/RecordLayoutBuilder.cpp | |
parent | fa3bee47569b1583e4319bbdbcd3f129345caa25 (diff) | |
download | bcm5719-llvm-20208cc046c206a1436edb714e94bd52a0bc8572.tar.gz bcm5719-llvm-20208cc046c206a1436edb714e94bd52a0bc8572.zip |
[ARM, AArch64]: Use unadjusted alignment when passing composites as arguments
The "Procedure Call Procedure Call Standard for the ARMĀ® Architecture"
(https://static.docs.arm.com/ihi0042/f/IHI0042F_aapcs.pdf), specifies that
composite types are passed according to their "natural alignment", i.e. the
alignment before alignment adjustment on the entire composite is applied.
The same applies for AArch64 ABI.
Clang, however, used the adjusted alignment.
GCC already implements the ABI correctly. With this patch Clang becomes
compatible with GCC and passes such arguments in accordance with AAPCS.
Differential Revision: https://reviews.llvm.org/D46013
llvm-svn: 338279
Diffstat (limited to 'clang/lib/AST/RecordLayoutBuilder.cpp')
-rw-r--r-- | clang/lib/AST/RecordLayoutBuilder.cpp | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index b4b09c7cecd..c92ac20f1f3 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -582,6 +582,9 @@ protected: /// The alignment if attribute packed is not used. CharUnits UnpackedAlignment; + /// \brief The maximum of the alignments of top-level members. + CharUnits UnadjustedAlignment; + SmallVector<uint64_t, 16> FieldOffsets; /// Whether the external AST source has provided a layout for this @@ -662,6 +665,7 @@ protected: EmptySubobjectMap *EmptySubobjects) : Context(Context), EmptySubobjects(EmptySubobjects), Size(0), Alignment(CharUnits::One()), UnpackedAlignment(CharUnits::One()), + UnadjustedAlignment(CharUnits::One()), UseExternalLayout(false), InferAlignment(false), Packed(false), IsUnion(false), IsMac68kAlign(false), IsMsStruct(false), UnfilledBitsInLastUnit(0), LastBitfieldTypeSize(0), @@ -1707,7 +1711,9 @@ void ItaniumRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) { setSize(std::max(getSizeInBits(), getDataSizeInBits())); // Remember max struct/class alignment. - UpdateAlignment(Context.toCharUnitsFromBits(FieldAlign), + UnadjustedAlignment = + std::max(UnadjustedAlignment, Context.toCharUnitsFromBits(FieldAlign)); + UpdateAlignment(Context.toCharUnitsFromBits(FieldAlign), Context.toCharUnitsFromBits(UnpackedFieldAlign)); } @@ -1862,6 +1868,7 @@ void ItaniumRecordLayoutBuilder::LayoutField(const FieldDecl *D, setSize(std::max(getSizeInBits(), getDataSizeInBits())); // Remember max struct/class alignment. + UnadjustedAlignment = std::max(UnadjustedAlignment, FieldAlign); UpdateAlignment(FieldAlign, UnpackedFieldAlign); } @@ -2988,7 +2995,8 @@ ASTContext::getASTRecordLayout(const RecordDecl *D) const { if (const auto *RD = dyn_cast<CXXRecordDecl>(D)) { Builder.cxxLayout(RD); NewEntry = new (*this) ASTRecordLayout( - *this, Builder.Size, Builder.Alignment, Builder.RequiredAlignment, + *this, Builder.Size, Builder.Alignment, Builder.Alignment, + Builder.RequiredAlignment, Builder.HasOwnVFPtr, Builder.HasOwnVFPtr || Builder.PrimaryBase, Builder.VBPtrOffset, Builder.DataSize, Builder.FieldOffsets, Builder.NonVirtualSize, Builder.Alignment, CharUnits::Zero(), @@ -2998,7 +3006,8 @@ ASTContext::getASTRecordLayout(const RecordDecl *D) const { } else { Builder.layout(D); NewEntry = new (*this) ASTRecordLayout( - *this, Builder.Size, Builder.Alignment, Builder.RequiredAlignment, + *this, Builder.Size, Builder.Alignment, Builder.Alignment, + Builder.RequiredAlignment, Builder.Size, Builder.FieldOffsets); } } else { @@ -3019,7 +3028,7 @@ ASTContext::getASTRecordLayout(const RecordDecl *D) const { CharUnits NonVirtualSize = skipTailPadding ? DataSize : Builder.NonVirtualSize; NewEntry = new (*this) ASTRecordLayout( - *this, Builder.getSize(), Builder.Alignment, + *this, Builder.getSize(), Builder.Alignment, Builder.UnadjustedAlignment, /*RequiredAlignment : used by MS-ABI)*/ Builder.Alignment, Builder.HasOwnVFPtr, RD->isDynamicClass(), CharUnits::fromQuantity(-1), DataSize, Builder.FieldOffsets, @@ -3032,7 +3041,7 @@ ASTContext::getASTRecordLayout(const RecordDecl *D) const { Builder.Layout(D); NewEntry = new (*this) ASTRecordLayout( - *this, Builder.getSize(), Builder.Alignment, + *this, Builder.getSize(), Builder.Alignment, Builder.UnadjustedAlignment, /*RequiredAlignment : used by MS-ABI)*/ Builder.Alignment, Builder.getSize(), Builder.FieldOffsets); } @@ -3186,6 +3195,7 @@ ASTContext::getObjCLayout(const ObjCInterfaceDecl *D, const ASTRecordLayout *NewEntry = new (*this) ASTRecordLayout(*this, Builder.getSize(), Builder.Alignment, + Builder.UnadjustedAlignment, /*RequiredAlignment : used by MS-ABI)*/ Builder.Alignment, Builder.getDataSize(), |