digitalmars.D.bugs - [Issue 16355] New: __xpostblit incorrectly generated for a struct
- via Digitalmars-d-bugs (55/55) Aug 05 2016 https://issues.dlang.org/show_bug.cgi?id=16355
https://issues.dlang.org/show_bug.cgi?id=16355 Issue ID: 16355 Summary: __xpostblit incorrectly generated for a struct with a zero-length static array Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: normal Priority: P1 Component: dmd Assignee: nobody puremagic.com Reporter: issues.dlang jmdavisProg.com I noticed that std.traits.hasElaborateCopyConstructor has an overly elaborate implementation where it recursively looks at each member of a struct to determine whether it has a postblit constructor. And that makes sense if you don't know about __xpostblit (which as I understand it is the function that calls the postblit constructor on any member variables that needs it as well as calling the postblit constructor on the struct itself). However, given that any struct that either has a postblit constructor or which has members with a postblit constructor should have __xpostblit, and any struct that does not have a postblit constructor or any membears with postblit constructors should not have __xpostblit, hasElaborateCopyConstructor should be able to just test whether the struct has __xpostblit or not rather than recursively checking for __postblit. However, when I made that change, the tests failed because of this struct static struct S6 { S3[0] field; } In particular, this code void main() { import std.traits; static struct S2 { this(this) {} } static struct S3 { S2 field; } static struct S6 { S3[0] field; } static assert(!hasElaborateCopyConstructor!S6, "assert 1"); static assert(!__traits(hasMember, S6, "__postblit"), "assert 2"); static assert(!__traits(hasMember, S6, "__xpostblit"), "assert 3"); } results in this compilation error q.d(9): Error: static assert "assert 3" Correctly, S6 does not have __postblit. However, the compiler apparently decided to give it an __xpostblit when it doesn't actually need one. Yes, the static array is of a struct that has a postblit constructor, but the static array has a length of 0, so it should never be necessary to call any postblit constructors when copying that array. Presumably, the dmd code sees that it's a static array of something with a postblit constructor without taking into account the fact that the array's length is 0 and thus that no postblit constructor will ever need to be called. So, I would argue that __xpostblit should be fixed to match hasElaborateCopyConstructor. But if for some reason, we decide that it actually does make sense for __xpostblit to be declared in this case (though I don't see why it would be), then this bug report should be changed to indicate that hasElaborateCopyConstructor needs to be fixed to match. --
Aug 05 2016