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>.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80964 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp
index 74ef2ea..f2fd885 100644
--- a/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -199,8 +199,15 @@
   }
   
   // 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/test/CodeGen/pragma-pack-3.c b/test/CodeGen/pragma-pack-3.c
new file mode 100644
index 0000000..b9166ae
--- /dev/null
+++ b/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;