]> granicus.if.org Git - clang/commitdiff
We don't pass classes with a copy-constructor or destructor byval, so the address...
authorEli Friedman <eli.friedman@gmail.com>
Wed, 29 Jun 2011 07:04:55 +0000 (07:04 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Wed, 29 Jun 2011 07:04:55 +0000 (07:04 +0000)
The fixed implementation is compatible with the implementation both gcc and llvm-gcc use.

rdar://9686430 . (This is the issue that was reported in the thread "[LLVMdev] Segfault calling LLVM libs from a clang-compiled executable".)

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134059 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/TargetInfo.cpp
test/CodeGenCXX/x86_64-arguments.cpp

index 47a764bbc00a3fcba1284bf52dcbbd8fbc5e06d4..f65fc185ba48ba06444e0ca41163149236fedd21 100644 (file)
@@ -1765,6 +1765,8 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType(QualType Ty, unsigned &neededInt,
     // COMPLEX_X87, it is passed in memory.
   case X87:
   case ComplexX87:
+    if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty))
+      ++neededInt;
     return getIndirectResult(Ty);
 
   case SSEUp:
index 01f1a445b1c73ec4968175fb1ac838b36d7bb93e..6d3748ca7d9114f5426afbbb54af1c44febe20e0 100644 (file)
@@ -115,3 +115,22 @@ namespace test6 {
   }
   // CHECK: define i32 @_ZN5test64testENS_5outerE(i64 %x.coerce0, i32 %x.coerce1)
 }
+
+namespace test7 {
+  struct StringRef {char* ptr; long len; };
+  class A { public: ~A(); };
+  A x(A, A, long, long, StringRef) { return A(); }
+  // Check that the StringRef is passed byval instead of expanded
+  // (which would split it between registers and memory).
+  // rdar://problem/9686430
+  // CHECK: define void @_ZN5test71xENS_1AES0_llNS_9StringRefE({{.*}} byval align 8)
+
+  // And a couple extra related tests:
+  A y(A, long double, long, long, StringRef) { return A(); }
+  // CHECK: define void @_ZN5test71yENS_1AEellNS_9StringRefE({{.*}} i8*
+  struct StringDouble {char * ptr; double d;};
+  A z(A, A, A, A, A, StringDouble) { return A(); }
+  A zz(A, A, A, A, StringDouble) { return A(); }
+  // CHECK: define void @_ZN5test71zENS_1AES0_S0_S0_S0_NS_12StringDoubleE({{.*}} byval align 8)
+  // CHECK: define void @_ZN5test72zzENS_1AES0_S0_S0_NS_12StringDoubleE({{.*}} i8*
+}