From 93fdb3f356ea25490d6eb3b8abf0f1c540b7cd4b Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Thu, 22 Oct 2015 18:04:22 +0000 Subject: [PATCH] [MS ABI] Don't crash when inheriting from base with trailing empty array member We got this right for Itanium but not MSVC because CGRecordLayoutBuilder was checking if the base's size was zero when it should have been checking the non-virtual size. This fixes PR21040. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@251036 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGRecordLayoutBuilder.cpp | 2 +- test/Layout/ms-x86-empty-nonvirtual-bases.cpp | 26 ++++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp index f91ecebd09..375b59c5cb 100644 --- a/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -454,7 +454,7 @@ void CGRecordLowering::accumulateBases() { // contain only a trailing array member. const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl(); if (!BaseDecl->isEmpty() && - !Context.getASTRecordLayout(BaseDecl).getSize().isZero()) + !Context.getASTRecordLayout(BaseDecl).getNonVirtualSize().isZero()) Members.push_back(MemberInfo(Layout.getBaseClassOffset(BaseDecl), MemberInfo::Base, getStorageType(BaseDecl), BaseDecl)); } diff --git a/test/Layout/ms-x86-empty-nonvirtual-bases.cpp b/test/Layout/ms-x86-empty-nonvirtual-bases.cpp index 00906e9862..07be1d836e 100644 --- a/test/Layout/ms-x86-empty-nonvirtual-bases.cpp +++ b/test/Layout/ms-x86-empty-nonvirtual-bases.cpp @@ -159,6 +159,28 @@ struct __declspec(align(32)) H : B0, B1, B2, B3, B4 { // CHECK-NEXT: | [sizeof=64, align=32 // CHECK-NEXT: | nvsize=40, nvalign=32] +struct I { + int i0[0]; +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK-NEXT: 0 | struct I +// CHECK-NEXT: 0 | int [0] i0 +// CHECK-NEXT: | [sizeof={{1|4}}, align=4, +// CHECK-NEXT: | nvsize=0, nvalign=4] + +struct J : I { + int j; +}; + +// CHECK: *** Dumping AST Record Layout +// CHECK-NEXT: 0 | struct J +// CHECK-NEXT: 0 | struct I (base) +// CHECK-NEXT: 0 | int [0] i0 +// CHECK-NEXT: 0 | int j +// CHECK-NEXT: | [sizeof=4, align=4, +// CHECK-NEXT: | nvsize=4, nvalign=4] + int a[ sizeof(A)+ sizeof(B)+ @@ -167,4 +189,6 @@ sizeof(D)+ sizeof(E)+ sizeof(F)+ sizeof(G)+ -sizeof(H)]; +sizeof(H)+ +sizeof(I)+ +sizeof(J)]; -- 2.40.0