dmd icon indicating copy to clipboard operation
dmd copied to clipboard

__traits(hasMember, T, "__xdtor") is true in some cases where there is no __xdtor member

Open dlangBugzillaToGithub opened this issue 1 year ago • 2 comments

Jonathan M Davis (@jmdavis) reported this on 2024-11-18T11:30:12Z

Transferred from https://issues.dlang.org/show_bug.cgi?id=24865

Description

This code

void main()
{
    import std.stdio;
    import std.traits;

    static struct S2 { ~this() { writeln("destroyed"); } }
    static struct S3 { S2 field; }
    static struct S6 { S3[0] field; }

    S6 s6;

    pragma(msg, "S2: " ~ __traits(allMembers, S2).stringof);
    pragma(msg, "S2: " ~ __traits(hasMember, S2, "__xdtor").stringof);

    pragma(msg, "S3: " ~ __traits(allMembers, S3).stringof);
    pragma(msg, "S3: " ~ __traits(hasMember, S3, "__xdtor").stringof);

    pragma(msg, "S6: " ~ __traits(allMembers, S6).stringof);
    pragma(msg, "S6: " ~ __traits(hasMember, S6, "__xdtor").stringof);
}

prints out

S2: AliasSeq!("__dtor", "__xdtor", "opAssign")
S2: true
S3: AliasSeq!("field", "__xdtor", "opAssign")
S3: true
S6: AliasSeq!("field", "opAssign")
S6: true

when compiling, and it prints out nothing when it runs.

S6 should not have a destructor, because while the elements of its static array have destructors, the static array has no length, and so, there's nothing to destroy. The fact that nothing prints out when running the program shows that S6 has no destructor. allMembers also has no __xdtor member, which lines up with the behavior of the running program. However, for some reason, hasMember reports that there is an __xdtor member.

Given that allMembers matches the actual behavior, I'm inclined to think that the bug is in hasMember rather than there being an invisible __xdtor that allMembers isn't reporting, but either way, there is a discrepancy here which needs to be fixed.

This affects the implementation of {core.internal,std}.traits.hasElaborateDestructor.

dlangBugzillaToGithub avatar Nov 18 '24 11:11 dlangBugzillaToGithub

S2 s2;
s2.__xdtor(); // compiles
S3 s3;
s3.__xdtor(); // compiles
S6 s6;
s6.__xdtor(); // Error: `this` for `~this` needs to be type `S3` not type `S6`

which is... not an error I would expect, but still fails.

thewilsonator avatar Apr 13 '25 07:04 thewilsonator

cc @RazvanN7 you last touched this for #15406

thewilsonator avatar Apr 13 '25 07:04 thewilsonator