diff options
-rw-r--r-- | lib/CodeGen/TargetInfo.cpp | 2 | ||||
-rw-r--r-- | test/CodeGenCXX/x86_64-arguments.cpp | 19 |
2 files changed, 21 insertions, 0 deletions
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index 47a764bbc0..f65fc185ba 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -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: diff --git a/test/CodeGenCXX/x86_64-arguments.cpp b/test/CodeGenCXX/x86_64-arguments.cpp index 01f1a445b1..6d3748ca7d 100644 --- a/test/CodeGenCXX/x86_64-arguments.cpp +++ b/test/CodeGenCXX/x86_64-arguments.cpp @@ -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* +} |