digitalmars.D.bugs - [Issue 21981] New: Manually calling a __dtor can violate memory safety
- d-bugmail puremagic.com (59/59) May 26 2021 https://issues.dlang.org/show_bug.cgi?id=21981
https://issues.dlang.org/show_bug.cgi?id=21981 Issue ID: 21981 Summary: Manually calling a __dtor can violate memory safety Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: enhancement Priority: P1 Component: dmd Assignee: nobody puremagic.com Reporter: thomas.bockman gmail.com The purpose of destructors is to describe cleanup work to be performed when the lifetime of an object is over. Allowing safe code to call a destructor manually before that point and then continue to use the destroyed object afterwards breaks RAII memory management: ///////////////////////////////////////////// module app; import core.stdc.stdlib : malloc, free; struct UniqueInt { private int* target; this(const(bool) doCreate) scope trusted nothrow nogc { target = cast(int*) malloc(int.sizeof); *target = 5; } disable this(this); disable this(ref typeof(this)); disable ref typeof(this) opAssign(ref typeof(this)); void withBorrow(void delegate(scope int*) safe action) safe { action(target); } ~this() scope trusted nothrow nogc { if(target !is null) { free(target); target = null; } } } UniqueInt unique; shared static this() { unique = true; } void main() safe { import std.stdio: writeln; unique.withBorrow((scope int* borrowed) safe { writeln(*borrowed); destroy(unique); writeln(*borrowed); // Use after free. }); } ///////////////////////////////////////////// I think the only reasonable solution to this is to make calling __dtor, __xdtor, or destroy manually an system operation, regardless of the attributes of ~this(). (I suspect there is some way to violate memory safety or break the type system with this even in 100% safe code, but I couldn't figure out what it is so I've marked this as an enhancement request.) Forum thread: https://forum.dlang.org/post/tkxneqmsbxfpomlnekhv forum.dlang.org --
May 26 2021