diff options
Diffstat (limited to 'contrib/llvm/patches/patch-r262262-clang-r199037-sparc.diff')
-rw-r--r-- | contrib/llvm/patches/patch-r262262-clang-r199037-sparc.diff | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/contrib/llvm/patches/patch-r262262-clang-r199037-sparc.diff b/contrib/llvm/patches/patch-r262262-clang-r199037-sparc.diff new file mode 100644 index 0000000..beed0ed --- /dev/null +++ b/contrib/llvm/patches/patch-r262262-clang-r199037-sparc.diff @@ -0,0 +1,53 @@ +Pull in r199037 from upstream clang trunk (by Jakob Stokund Olesen): + + SPARC passes non-trivial C++ objects indirectly like everybody else. + +Introduced here: http://svn.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<llvm::StructType>(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); ++} |