From: Ulrich Weigand Date: Wed, 29 Oct 2014 13:23:20 +0000 (+0000) Subject: [PowerPC ABI] Bug 21398 - Consider C++ base classes in HA classification X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6ea747c1d6f56c693a65a486fc2c8d8efed3ea90;p=clang [PowerPC ABI] Bug 21398 - Consider C++ base classes in HA classification As discussed in bug 21398, PowerPC ABI code needs to consider C++ base classes when classifying a class as homogeneous aggregate (or not) for ABI purposes. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@220852 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index ea62e4e409..4fcfc79abd 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -3208,6 +3208,22 @@ PPC64_SVR4_ABIInfo::isHomogeneousAggregate(QualType Ty, const Type *&Base, return false; Members = 0; + + // If this is a C++ record, check the bases first. + if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) { + for (const auto &I : CXXRD->bases()) { + // Ignore empty records. + if (isEmptyRecord(getContext(), I.getType(), true)) + continue; + + uint64_t FldMembers; + if (!isHomogeneousAggregate(I.getType(), Base, FldMembers)) + return false; + + Members += FldMembers; + } + } + for (const auto *FD : RD->fields()) { // Ignore (non-zero arrays of) empty records. QualType FT = FD->getType(); diff --git a/test/CodeGen/ppc64le-aggregates-cpp.cpp b/test/CodeGen/ppc64le-aggregates-cpp.cpp new file mode 100644 index 0000000000..7e7dde83f6 --- /dev/null +++ b/test/CodeGen/ppc64le-aggregates-cpp.cpp @@ -0,0 +1,39 @@ +// REQUIRES: powerpc-registered-target +// RUN: %clang_cc1 -triple powerpc64le-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s + +// Test that C++ classes are correctly classified as homogeneous aggregates. + +struct Base1 { + int x; +}; +struct Base2 { + double x; +}; +struct Base3 { + double x; +}; +struct D1 : Base1 { // non-homogeneous aggregate + double y, z; +}; +struct D2 : Base2 { // homogeneous aggregate + double y, z; +}; +struct D3 : Base1, Base2 { // non-homogeneous aggregate + double y, z; +}; +struct D4 : Base2, Base3 { // homogeneous aggregate + double y, z; +}; + +// CHECK: define void @_Z7func_D12D1(%struct.D1* noalias sret %agg.result, [3 x i64] %x.coerce) +D1 func_D1(D1 x) { return x; } + +// CHECK: define [3 x double] @_Z7func_D22D2([3 x double] %x.coerce) +D2 func_D2(D2 x) { return x; } + +// CHECK: define void @_Z7func_D32D3(%struct.D3* noalias sret %agg.result, [4 x i64] %x.coerce) +D3 func_D3(D3 x) { return x; } + +// CHECK: define [4 x double] @_Z7func_D42D4([4 x double] %x.coerce) +D4 func_D4(D4 x) { return x; } +