From 9c23bab9b02f3bc699d12d51cc8dc3c22d2548bf Mon Sep 17 00:00:00 2001 From: Yunzhong Gao 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 6a5b6decc8..a1cc2aec50 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 0000000000..e244ef55df --- /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; -- 2.40.0