This fixes PR15768, where the sret parameter and the 'this' parameter are in the wrong order. Instance methods compiled by MSVC never return records in registers, they always return indirectly through an sret pointer. That sret pointer always comes after the 'this' parameter, for both __cdecl and __thiscall methods. Unfortunately, the same is true for other calling conventions, so we'll have to change the overall approach here relatively soon. Reviewers: rsmith Differential Revision: http://llvm-reviews.chandlerc.com/D2664 llvm-svn: 200587
36 lines
1.2 KiB
C++
36 lines
1.2 KiB
C++
// RUN: %clang_cc1 -triple i386-pc-win32 -emit-llvm %s -o - | FileCheck %s
|
|
|
|
// PR15768
|
|
|
|
// A trivial 12 byte struct is returned indirectly.
|
|
struct S {
|
|
S();
|
|
int a, b, c;
|
|
};
|
|
|
|
struct C {
|
|
S variadic_sret(const char *f, ...);
|
|
S __cdecl cdecl_sret();
|
|
S __cdecl byval_and_sret(S a);
|
|
int c;
|
|
};
|
|
|
|
S C::variadic_sret(const char *f, ...) { return S(); }
|
|
S C::cdecl_sret() { return S(); }
|
|
S C::byval_and_sret(S a) { return S(); }
|
|
|
|
// CHECK: define x86_cdeclmethodcc void @"\01?variadic_sret@C@@QAA?AUS@@PBDZZ"(%struct.S* noalias sret %agg.result, %struct.C* %this, i8* %f, ...)
|
|
// CHECK: define x86_cdeclmethodcc void @"\01?cdecl_sret@C@@QAA?AUS@@XZ"(%struct.S* noalias sret %agg.result, %struct.C* %this)
|
|
// CHECK: define x86_cdeclmethodcc void @"\01?byval_and_sret@C@@QAA?AUS@@U2@@Z"(%struct.S* noalias sret %agg.result, %struct.C* %this, %struct.S* byval align 4 %a)
|
|
|
|
int main() {
|
|
C c;
|
|
c.variadic_sret("asdf");
|
|
c.cdecl_sret();
|
|
c.byval_and_sret(S());
|
|
}
|
|
// CHECK-LABEL: define i32 @main()
|
|
// CHECK: call x86_cdeclmethodcc void {{.*}} @"\01?variadic_sret@C@@QAA?AUS@@PBDZZ"
|
|
// CHECK: call x86_cdeclmethodcc void @"\01?cdecl_sret@C@@QAA?AUS@@XZ"
|
|
// CHECK: call x86_cdeclmethodcc void @"\01?byval_and_sret@C@@QAA?AUS@@U2@@Z"
|