Description
Win32's cdecl callconv is different from linux's cdecl on returning large structs. For example (from test suite),
struct TwoU64s {
uint64_t one;
uint64_t two;
};
TwoU64s rust_dbg_extern_identity_TwoU64s(TwoU64s u) {
return u;
}
On linux or mingw (gcc <=4.6), the function ends with:
ret $0x4
This means callee cleans stack for extra space. However, msvc (cl.exe) treats it differently:
ret
then caller is expected to clean 4 bytes.
This implies it will hurt stack if mingw caller calls msvc function.
It is a known issue, and is reported at gcc bugzilla and at mingw.
However, mingw's recent gcc follows win32 convention. (mingw-w64's gcc 4.8 also does.)
This is good for msvc compatibility, however it causes make check-fast
failure on latest mingw:
task <unnamed> failed at 'assertion failed: `(left == right) &&
(right == left)`
(left: `t_317::TwoU64s{one: 98784247808u64, two: 257698037760u64}`,
right: `t_317::TwoU64s{one: 22u64, two: 94489280535u64}`)',
C:\home\stone\rust-vanilla\src\test\run-pass\extern-pass-TwoU64s-ref.rs:27
make: *** [i686-pc-mingw32/test/run_pass_stage2_driver-i686-pc-mingw32.out]
Error 101
Relevant codes are: extern-pass-TwoU64s-ref.rs, rust_test_helpers.cpp.
(Well, to build rust with latest mingw, you need some hacks: 1, 2.)
I think we should follow msvc's calling convention on Win32. It implies that we (and bors) have to upgrade mingw later.