New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue 21693 - Lower scoped destruction of extern(C++) class to destroy/dtor call #12265
Conversation
eda3dc3
to
07d299b
Compare
Thanks for your pull request and interest in making D better, @MoonlightSentinel! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please see CONTRIBUTING.md for more information. If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment. Bugzilla references
Testing this PR locallyIf you don't have a local development environment setup, you can use Digger to test this PR: dub run digger -- build "stable + dmd#12265" |
if (mynew || onstack) // if any destructors | ||
{ | ||
// delete'ing C++ classes crashes (and delete is deprecated anyway) | ||
if (cd.classKind == ClassKind.cpp) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
destroy
should be used instead of delete
for for D classes, too: https://issues.dlang.org/show_bug.cgi?id=21692
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
destroy
doesn't work for const
/immutable
either (unless we insert an explicit cast to mutable)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implemented another approach, it's now directly calling the dtor (effectively inlining the call to destroy
).
This matches the implementation for struct
s and allows the hack to call dtors on immutable instances.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
destroy doesn't work for const/immutable either (unless we insert an explicit cast to mutable)
Seems like it does (tested with v2.096.0). Anyway, the direct dtor call is better. Is there a reason you don't use it for D classes too? I find it inconsistent (can use scope const/immutable
with C++ classes, but not with D ones) and don't really like deprecated expressions in compiler-generated AST nodes. ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like it does (tested with v2.096.0).
Nevermind, seems like it was an issue with the lowering.
Is there a reason you don't use it for D classes too? I find it inconsistent (can use scope const/immutable with C++ classes, but not with D ones) and don't really like deprecated expressions in compiler-generated AST nodes. ;)
Mostly because destroy
(and delete
IIRC) refer to rt_finalize2
which does more cleanup than just calling the dtor. Not sure if those additional steps are required for stack allocated instances...
But lowering to destroy
would still work for D classes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But lowering to destroy would still work for D classes.
Yeah that'd be great.
You're right, for D classes, there's apparently the need to descend to all base classes and invoke the dtors manually (via TypeInfo... argh), and the monitor might need cleanup too. LDC has a special case for these delete
expressions for scope
classes and tries to avoid calling druntime if the class has no finalizer and the monitor is null: https://github.com/ldc-developers/ldc/blob/937c57b8354d4821daededb35abdb77d16ce3737/gen/classes.cpp#L200-L222
Doing this here in the frontend directly would obviously be much nicer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe the best way forward is to replace the TypeInfo
based dtor-loop in DRuntime with a real dtor chain as done for C++ classes and to move the cleanup into `Object.~this()). That would cause less (magic) code scattered across dmd/druntime/ldc/... .
Anyway, lowering to destroy
doesn't work yet.
- it isn't alway
@nogc
- CTFE cannot handle
destroy
(it needs some special casing as done fordelete
)
98de8e4
to
da70229
Compare
Ensures proper RAII behaviour for stack allocated instances but doesn't affect the behaviour for heap allocated instances. The previous rewrite used `delete` which relies on `TypeInfo` and crashed at runtime. Using `object.destroy` circumvents this issue (and is also beneficial due to the deprecation of `delete`). `destroy` can be used instead of `delete` because the instances live on the heap and hence don't need to be deallocated.
Call the destructor directly instead of referring to object.destroy
da70229
to
aa2147b
Compare
Ensures proper RAII behaviour for stack allocated instances but doesn't affect the behaviour for heap allocated instances.
The previous rewrite used
delete
which relies onTypeInfo
and crashed at runtime. Usingobject.destroy
circumvents this issue (and is also beneficial due to the deprecation ofdelete
).destroy
can be used instead ofdelete
because the instances live on the heap and hence don't need to be deallocated.