Bug 19563 – extern(C++) Incorrect ABI passing small struct

Status
RESOLVED
Resolution
FIXED
Severity
blocker
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2019-01-09T08:22:47Z
Last change time
2022-11-24T07:05:42Z
Keywords
C++, industry, wrong-code
Assigned to
No Owner
Creator
Manu
See also
https://issues.dlang.org/show_bug.cgi?id=23195

Comments

Comment #0 by turkeyman — 2019-01-09T08:22:47Z
test.cpp -------- struct Test { Test() : ptr(nullptr) {} Test(const Test& x) { ptr = x.ptr + 10; } char* ptr; }; int test(Test p); int main() { Test x; test(x); return 0; } test.d ------ extern(C++): struct Test { this(this) { ptr += 10; } char* ptr; } int test(Test p) { assert(p.ptr == null); return 10; } -------------------------------------------- When I build and run this, passing `x` to test() by value crashes. The function receives garbage. If you remove the copy constructors (pass this same struct as a POD), it works fine! This was tested in Linux 64bit, against GCC-7. If it makes any difference, I supplied `-std=c++11 -D_GLIBCXX_USE_CXX11_ABI=0` to the C compiler.
Comment #1 by sprink.noreply — 2019-02-08T01:54:57Z
Appears DMD doesn't take into consideration how to pass a struct based on anything other than the size of the struct. The Itantium ABI passes a pointer to the object if it has a copy constructor or destructor. https://github.com/dlang/dmd/blob/v2.084.0/src/dmd/target.d#L688 https://github.com/dlang/dmd/blob/v2.084.0/src/dmd/backend/cod1.d#L4033 Somewhere in that mess of a backend. Good luck! Either make sure your structs are more than 8 bytes as a workaround, or just use LDC they tend to have better C++ interactions.
Comment #2 by turkeyman — 2019-03-04T03:46:56Z
If anyone knows how to fix this; here's a head-start: https://github.com/dlang/dmd/pull/9411 That commits the unit-test which needs to work.
Comment #3 by turkeyman — 2019-03-04T03:49:01Z
This bug blocks the druntime `std::string` PR.
Comment #4 by dlang-bot — 2019-03-09T20:47:36Z
@look-at-me created dlang/dmd pull request #9434 "Fix Issue 19563 Fix extern(C++) Incorrect ABI passing small struct" mentioning this issue: - Fix Issue 19563 Fix extern(C++) Incorrect ABI passing small struct https://github.com/dlang/dmd/pull/9434
Comment #5 by dlang-bot — 2019-03-12T02:46:26Z
dlang/dmd pull request #9434 "Fix Issue 19563 Fix extern(C++) Incorrect ABI passing small struct" was merged into master: - bb2892490ee0df3f3fda486e8e549fdb4e58e37b by look-at-me: Fix Issue 19563 Fix extern(C++) Incorrect ABI passing small struct https://github.com/dlang/dmd/pull/9434
Comment #6 by bugzilla — 2022-11-24T07:03:59Z
This problem appears to have been introduced by https://github.com/dlang/dmd/pull/9434/
Comment #7 by bugzilla — 2022-11-24T07:05:42Z
(In reply to Walter Bright from comment #6) > This problem appears to have been introduced by > https://github.com/dlang/dmd/pull/9434/ I mean it caused https://issues.dlang.org/show_bug.cgi?id=23195