From: David Majnemer Date: Thu, 22 Oct 2015 18:04:22 +0000 (+0000) Subject: [MS ABI] Don't crash when inheriting from base with trailing empty array member X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=93fdb3f356ea25490d6eb3b8abf0f1c540b7cd4b;p=clang [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 --- 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)];