From 6316508c3914c322888cc991670ae41e60367ab6 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Sun, 12 Jan 2014 06:54:56 +0000 Subject: [PATCH] SPARC passes non-trivial C++ objects indirectly like everybody else. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@199037 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/TargetInfo.cpp | 5 +++++ test/CodeGenCXX/sparcv9-abi.cpp | 26 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 test/CodeGenCXX/sparcv9-abi.cpp diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index da627756c8..2fbbda503f 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -5362,6 +5362,11 @@ SparcV9ABIInfo::classifyType(QualType Ty, unsigned SizeLimit) const { if (!isAggregateTypeForABI(Ty)) return ABIArgInfo::getDirect(); + // If a C++ object has either a non-trivial copy constructor or a non-trivial + // destructor, it is passed with an explicit indirect pointer / sret pointer. + if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) + return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory); + // This is a small aggregate type that should be passed in registers. // Build a coercion type from the LLVM struct type. llvm::StructType *StrTy = dyn_cast(CGT.ConvertType(Ty)); diff --git a/test/CodeGenCXX/sparcv9-abi.cpp b/test/CodeGenCXX/sparcv9-abi.cpp new file mode 100644 index 0000000000..128d648ceb --- /dev/null +++ b/test/CodeGenCXX/sparcv9-abi.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -triple sparcv9-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +struct pod { + int a, b; +}; + +void f0(); +void f1(struct pod); + +struct notpod { + int a, b; + ~notpod() { f0(); } +}; + +void f2(struct notpod); + +// CHECK-LABEL: caller +// CHECK: call void @_Z2f13pod(i64 +// CHECK: call void @_Z2f26notpod(%struct.notpod* +void caller() +{ + pod p1; + notpod p2; + f1(p1); + f2(p2); +} -- 2.40.0