]> granicus.if.org Git - clang/commitdiff
Before determining the effect the alignment of base struct will have in the aligment...
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Thu, 9 Dec 2010 00:35:20 +0000 (00:35 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Thu, 9 Dec 2010 00:35:20 +0000 (00:35 +0000)
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
test/SemaCXX/pragma-pack.cpp [new file with mode: 0644]

index ba7be0ac692d3377c9d5d87ebb42e33f3f43a1ce..b1114253fc82ead80481eff966a6fa40dd805199 100644 (file)
@@ -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 (file)
index 0000000..c388bd4
--- /dev/null
@@ -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];
+
+}