The logic std.format uses for detecting overlap of anonymous unions is incorrect. It looks at the difference in .offsetof for consecutive members in .tupleof, but doesn't account for nested unions. ``` import std; struct S { union { struct { union { string a = "string a"; long overlapsAlength; } string b = "string b"; } string[2] overlapsAandB; } } void main() @safe { S s; s.overlapsAlength = 32; writeln(s); } ``` Prints: S(#{overlap a, overlapsAlength}, "string b", ["string a\0string b\0%s\0/dlang/dmd-", "string b"]) It only detects the overlap of `a` and `overlapsAlength`, while `overlapsAandB` gets printed, resulting in memory corruption. The example calls writeln on s, but writeln is simply a wrapper around formatValue which is at the heart of the issue: ``` auto a = appender!string; auto f = singleSpec("%s"); formatValue(a, s, f); writeln(a.data); ``` The specific logic can be found here: https://github.com/dlang/phobos/blob/cc977c37b8fa7af5fc54bc64a6aad14714e5cf2d/std/format.d#L4411
IMHO, there is more about this: members of unions are only printed, if they are members of structs, but not stand alone unions. They are just formatted as their name. I think, either, members of unions should always be printed (and then correctly) or not at all.
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/phobos/issues/9786 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB