summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/patches/patch-r262262-clang-r199037-sparc.diff
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/patches/patch-r262262-clang-r199037-sparc.diff')
-rw-r--r--contrib/llvm/patches/patch-r262262-clang-r199037-sparc.diff53
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);
++}
OpenPOWER on IntegriCloud