From 43ddd9f2027bdd9c36336a342e9c0dd2aa13f836 Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Thu, 9 Dec 2010 00:35:20 +0000 Subject: [PATCH] Before determining the effect the alignment of base struct will have in the aligment of the sub-struct, take into account if the sub-struct is packed and its maximum field alignment. Fixes rdar://8745206 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@121335 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/RecordLayoutBuilder.cpp | 11 +++++++++-- test/SemaCXX/pragma-pack.cpp | 16 ++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 test/SemaCXX/pragma-pack.cpp diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp index ba7be0ac69..b1114253fc 100644 --- a/lib/AST/RecordLayoutBuilder.cpp +++ b/lib/AST/RecordLayoutBuilder.cpp @@ -1092,7 +1092,14 @@ CharUnits RecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) { return CharUnits::Zero(); } - unsigned BaseAlign = Layout.getNonVirtualAlign(); + unsigned UnpackedBaseAlign = Layout.getNonVirtualAlign(); + unsigned BaseAlign = (Packed) ? 8 : UnpackedBaseAlign; + + // The maximum field alignment overrides base align. + if (MaxFieldAlignment) { + BaseAlign = std::min(BaseAlign, MaxFieldAlignment); + UnpackedBaseAlign = std::min(UnpackedBaseAlign, MaxFieldAlignment); + } // Round up the current record size to the base's alignment boundary. uint64_t Offset = llvm::RoundUpToAlignment(DataSize, BaseAlign); @@ -1110,7 +1117,7 @@ CharUnits RecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) { Size = std::max(Size, Offset + Layout.getSize()); // Remember max struct/class alignment. - UpdateAlignment(BaseAlign); + UpdateAlignment(BaseAlign, UnpackedBaseAlign); return toCharUnits(Offset); } diff --git a/test/SemaCXX/pragma-pack.cpp b/test/SemaCXX/pragma-pack.cpp new file mode 100644 index 0000000000..c388bd41af --- /dev/null +++ b/test/SemaCXX/pragma-pack.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -triple i686-apple-darwin9 -fsyntax-only -verify %s + +namespace rdar8745206 { + +struct Base { + int i; +}; + +#pragma pack(1) +struct Sub : public Base { + char c; +}; + +int check[sizeof(Sub) == 5 ? 1 : -1]; + +} -- 2.40.0