summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-09-03 22:56:02 +0000
committerAnders Carlsson <andersca@mac.com>2009-09-03 22:56:02 +0000
commit0e91275ab46cf44db15a1a1b07cb97210b38518e (patch)
tree8096429cf93ba5b23b3d37954dbeefaeca1c9733
parentaa92dc1e6148ae5d1b7c03b98d308958b9f49846 (diff)
downloadbcm5719-llvm-0e91275ab46cf44db15a1a1b07cb97210b38518e.tar.gz
bcm5719-llvm-0e91275ab46cf44db15a1a1b07cb97210b38518e.zip
If the alignment of the chosen field in a union is greater than the alignment of the union, we need to use a packed LLVM struct. Fixes <rdar://problem/7184250>.
llvm-svn: 80964
-rw-r--r--clang/lib/CodeGen/CGRecordLayoutBuilder.cpp9
-rw-r--r--clang/test/CodeGen/pragma-pack-3.c19
2 files changed, 27 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
index 74ef2eacc98..f2fd885ee4d 100644
--- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -199,8 +199,15 @@ void CGRecordLayoutBuilder::LayoutUnion(const RecordDecl *D) {
}
// Now add our field.
- if (Ty)
+ if (Ty) {
AppendField(0, Ty);
+
+ if (getTypeAlignment(Ty) > Layout.getAlignment() / 8) {
+ // We need a packed struct.
+ Packed = true;
+ Align = 1;
+ }
+ }
// Append tail padding.
if (Layout.getSize() / 8 > Size)
diff --git a/clang/test/CodeGen/pragma-pack-3.c b/clang/test/CodeGen/pragma-pack-3.c
new file mode 100644
index 00000000000..b9166ae5d39
--- /dev/null
+++ b/clang/test/CodeGen/pragma-pack-3.c
@@ -0,0 +1,19 @@
+// RUN: clang-cc -triple i386-apple-darwin9 %s -emit-llvm -o - | FileCheck -check-prefix X32 %s &&
+// CHECK-X32: %struct.menu = type <{ i8*, i8, i8 }>
+// CHECK-X32: %union.command = type <{ i8*, [2 x i8] }>
+
+// RUN: clang-cc -triple x86_64-apple-darwin9 %s -emit-llvm -o - | FileCheck -check-prefix X64 %s
+// CHECK-X64: %struct.menu = type <{ i8*, i8, i8 }>
+// CHECK-X64: %union.command = type <{ i8*, [2 x i8] }>
+
+// <rdar://problem/7184250>
+#pragma pack(push, 2)
+typedef union command {
+ void *windowRef;
+ struct menu {
+ void *menuRef;
+ unsigned char menuItemIndex;
+ } menu;
+} command;
+
+command c;
OpenPOWER on IntegriCloud