Win64: Fix extern(C++) ABI wrt. passing non-POD structs by value#2706
Win64: Fix extern(C++) ABI wrt. passing non-POD structs by value#2706kinke merged 1 commit intoldc-developers:masterfrom
Conversation
|
The dmd-testsuite tests work for Win32 and Win64, so both ABI (LL ref vs. value) and destruction rules (MSVC++ lets the callee destruct the param, just like D) match across D and C++, which is pretty nice. Maybe there's a slight chance that 32-bit POSIX passes the tests too, I haven't checked yet. There's still at least one remaining special case not covered yet, and that's MSVC++ apparently treating |
Nope, 32-bit Linux fails with a segfault; like for x86_64, a ref is passed, and the caller destructs it. |
|
Erm, turns out this only fixes the case where there's a deleted copy ctor and a move ctor, where 64-bit MSVC++ really passes a ref. With copy ctor, the argument is passed by value in a register, but the return value is still returned via hidden sret (!!), so the existing code and the inconsistent POD-ness check for return/param types is actually correct. A deleted C++ copy ctor apparently enforces by-ref passing though... |
|
I reworked this, especially the tests. They don't handle all permutations and corner cases of course, but the resulting fix should make byval-interop with C++ on Windows/MSVC work in most cases now. |
Most small non-PODs are passed in registers, but those with a C++ copy ctor, including an explicitly deleted one, are apparently passed by ref.
|
[Slightly reworked once more.] |
Return types have been checked for POD-ness already, but parameters haven't.