From 9c23bab9b02f3bc699d12d51cc8dc3c22d2548bf Mon Sep 17 00:00:00 2001
From: Yunzhong Gao <Yunzhong_Gao@playstation.sony.com>
Date: Fri, 24 Jan 2014 19:28:24 +0000
Subject: [PATCH] Fixing PR18510 by checking whether the non-virtual base of
 the derived class might have a smaller size as compared to the stand-alone
 type of the base class. This is possible when the derived class is packed and
 hence might have smaller alignment requirement than the base class.

Differential Revision: http://llvm-reviews.chandlerc.com/D2599



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@200031 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/CodeGen/CGRecordLayoutBuilder.cpp |  7 ++++++-
 test/CodeGenCXX/pragma-pack-3.cpp     | 17 +++++++++++++++++
 2 files changed, 23 insertions(+), 1 deletion(-)
 create mode 100644 test/CodeGenCXX/pragma-pack-3.cpp

diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp
index 6a5b6decc83..a1cc2aec506 100644
--- a/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -558,7 +558,12 @@ bool CGRecordLayoutBuilder::LayoutBase(const CXXRecordDecl *base,
   if (getTypeAlignment(subobjectType) > Alignment)
     return false;
 
-  AppendField(baseOffset, subobjectType);
+  if (LastLaidOutBase.NonVirtualSize < CharUnits::fromQuantity(
+      Types.getDataLayout().getStructLayout(subobjectType)->getSizeInBytes()))
+    AppendBytes(LastLaidOutBase.NonVirtualSize);
+  else
+    AppendField(baseOffset, subobjectType);
+
   return true;
 }
 
diff --git a/test/CodeGenCXX/pragma-pack-3.cpp b/test/CodeGenCXX/pragma-pack-3.cpp
new file mode 100644
index 00000000000..e244ef55df3
--- /dev/null
+++ b/test/CodeGenCXX/pragma-pack-3.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 %s -triple=i686-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+struct Base {
+  char a;
+};
+
+struct Derived_1 : virtual Base
+{
+  char b;
+};
+
+#pragma pack(1)
+struct Derived_2 : Derived_1 {
+  // CHECK: %struct.Derived_2 = type <{ [5 x i8], %struct.Base }>
+};
+
+Derived_2 x;
-- 
GitLab