[Issue 21981] New: Manually calling a __dtor can violate memory safety

d-bugmail at puremagic.com d-bugmail at puremagic.com
Wed May 26 21:59:50 UTC 2021


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 at puremagic.com
          Reporter: thomas.bockman at 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

--


More information about the Digitalmars-d-bugs mailing list