Pull in r199037 from upstream clang trunk (by Jakob Stokund Olesen): SPARC passes non-trivial C++ objects indirectly like everybody else. Introduced here: http://svnweb.freebsd.org/changeset/base/262262 Index: tools/clang/lib/CodeGen/TargetInfo.cpp =================================================================== --- tools/clang/lib/CodeGen/TargetInfo.cpp +++ tools/clang/lib/CodeGen/TargetInfo.cpp @@ -5349,6 +5349,11 @@ SparcV9ABIInfo::classifyType(QualType Ty, unsigned 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)); Index: tools/clang/test/CodeGenCXX/sparcv9-abi.cpp =================================================================== --- tools/clang/test/CodeGenCXX/sparcv9-abi.cpp +++ tools/clang/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); +}