]> granicus.if.org Git - clang/commitdiff
Fixing PR18510 by checking whether the non-virtual base of the derived class
authorYunzhong Gao <Yunzhong_Gao@playstation.sony.com>
Fri, 24 Jan 2014 19:28:24 +0000 (19:28 +0000)
committerYunzhong Gao <Yunzhong_Gao@playstation.sony.com>
Fri, 24 Jan 2014 19:28:24 +0000 (19:28 +0000)
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
test/CodeGenCXX/pragma-pack-3.cpp [new file with mode: 0644]

index 6a5b6decc833f8f3686c6b25a57ee6b399b9d616..a1cc2aec506878bfd22685855d28a9a703a73e88 100644 (file)
@@ -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 (file)
index 0000000..e244ef5
--- /dev/null
@@ -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;