Bug 20235 – C++ ABI doesn't destruct struct arguments in the callee

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2019-09-21T17:58:57Z
Last change time
2021-01-31T09:09:21Z
Keywords
industry, pull, wrong-code
Assigned to
No Owner
Creator
Suleyman Sahmi (سليمان السهمي)

Comments

Comment #0 by sahmi.soulaimane — 2019-09-21T17:58:57Z
C++ doesn't call the destructor or value parameters in the callee. C++: ``` struct S { ~S(){} }; void fuc(S) { } ``` https://cpp.godbolt.org/z/NJt_5s No call to the destructor. D: ``` extern(C++): struct S { ~this(){} } void fuc(S) { } ``` https://d.godbolt.org/z/5yzcFS It calls the destructor. This causes some double free bugs.
Comment #1 by kinke — 2019-09-21T19:07:03Z
(In reply to Suleyman Sahmi (سليمان السهمي) from comment #0) > This causes some double free bugs. Double free/destruction if caller is in C++ and callee in D, no destruction at all the other way around.
Comment #2 by sahmi.soulaimane — 2019-09-22T02:55:18Z
> Double free/destruction if caller is in C++ and callee in D, no destruction at all the other way around. Yes.
Comment #3 by dlang-bot — 2019-11-29T13:26:11Z
@SSoulaimane updated dlang/dmd pull request #10593 "Fix issue 20235 - caller destroys arguments on POSIX" fixing this issue: - Fix issue 20235 - caller destroys arguments on POSIX On Windows arguments are destroyed in the callee regardless of which calling convention is used (cdecl, stdcall... etc), 32bits and 64bits alike. On the other platforms, the caller destroys the arguments if the caller cleans the stack. https://github.com/dlang/dmd/pull/10593
Comment #4 by dlang-bot — 2020-12-01T06:11:59Z
@WalterBright created dlang/dmd pull request #12012 "Reboot of Fix issue 20235 - caller destroys arguments on POSIX #10593" fixing this issue: - Fix issue 20235 - caller destroys arguments on POSIX On Windows arguments are destroyed in the callee regardless of which calling convention is used (cdecl, stdcall... etc), 32bits and 64bits alike. On the other platforms, the caller destroys the arguments if the caller cleans the stack. https://github.com/dlang/dmd/pull/12012
Comment #5 by dlang-bot — 2021-01-28T08:33:04Z
dlang/dmd pull request #12012 "Reboot of Fix issue 20235 - caller destroys arguments on POSIX #10593" was merged into master: - 87206db1c37c22b5bfab5a46aa0cf56192a903c5 by سليمان السهمي (Suleyman Sahmi): Fix issue 20235 - Caller destroys arguments on POSIX On Windows, arguments are destroyed in the callee, regardless of which calling convention is used (cdecl, stdcall... etc), 32bits and 64bits alike. On the other platforms, the caller destroys the arguments if the caller cleans the stack. This changes the backend to respect the POSIX ABI on POSIX, allowing to correctly pass C++ objects by value accross language boundaries. Co-authored-by: Walter Bright <[email protected]> https://github.com/dlang/dmd/pull/12012
Comment #6 by dlang-bot — 2021-01-31T09:09:21Z
dlang/dmd pull request #12162 "Issue 20235 - Simplify fix by not declaring __gate" was merged into master: - 1c681d504f5b696c09d1755bb3630dc1790c61ff by Martin Kinkelin: Issue 20235 - Simplify fix by not declaring __gate Following Martin Kinkelin's comment in PR #12012: > We have the edtor `=> (__gate || edtor)` rewrite. > IIRC, the whole point of this `__gate` is to transfer ownership > of all temporary args requiring destruction to the callee just before the call > (i.e., if all arguments were constructed successfully without throw). > For `extern(D)`, it's up to the callee to destruct the parameter > [which, low-level wise, is either the original argument passed by ref or a moved/blitted instance]. > > So if `callerDestroysArgs == true`, it should suffice to keep the original `edtor` > and not declaring+setting `__gate`. Source: https://github.com/dlang/dmd/pull/12012#event-4259809188 https://github.com/dlang/dmd/pull/12162