Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions std/format/internal/write.d
Original file line number Diff line number Diff line change
Expand Up @@ -2546,9 +2546,23 @@ if ((is(T == struct) || is(T == union)) && (hasToString!(T, Char) || !is(Builtin
{
// ignore hidden context pointer
}
else static if (0 < i && T.tupleof[i-1].offsetof == T.tupleof[i].offsetof)
/* https://github.com/dlang/phobos/issues/10840
* handle possible bitfields by doing overlap comparisons
* using bit counts rather than byte counts.
* However, the overlap
* check in general does not take into account staggered unions.
* This can be fixed using the correct algorithm implemented in
* the compiler function dmd.declaration.isOverlappedWith().
Comment on lines +2552 to +2555
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI tracking this issue with staggered unions in #10844

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good!

* For the moment we will not change to that because the `#(overlap ...)` output
* needs to be re-thought, as it was never correct.
*/
else static if (0 < i &&
T.tupleof[i-1].offsetof * 8 + __traits(getBitfieldOffset,T.tupleof[i-1]) ==
T.tupleof[i ].offsetof * 8 + __traits(getBitfieldOffset,T.tupleof[i ]))
{
static if (i == T.tupleof.length - 1 || T.tupleof[i].offsetof != T.tupleof[i+1].offsetof)
static if (i == T.tupleof.length - 1 ||
T.tupleof[i ].offsetof * 8 + __traits(getBitfieldOffset,T.tupleof[i ]) !=
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't realise getBitfieldOffset worked for non-bitfields.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I implemented it that way for exactly this reason! It greatly simplifies the overlap logic. You'll see the same thing in the dmd source code, as referenced.

T.tupleof[i+1].offsetof * 8 + __traits(getBitfieldOffset,T.tupleof[i+1]))
{
enum el = separator ~ __traits(identifier, T.tupleof[i]) ~ "}";
put(w, el);
Expand All @@ -2559,7 +2573,9 @@ if ((is(T == struct) || is(T == union)) && (hasToString!(T, Char) || !is(Builtin
put(w, el);
}
}
else static if (i+1 < T.tupleof.length && T.tupleof[i].offsetof == T.tupleof[i+1].offsetof)
else static if (i+1 < T.tupleof.length &&
T.tupleof[i ].offsetof * 8 + __traits(getBitfieldOffset,T.tupleof[i ]) ==
T.tupleof[i+1].offsetof * 8 + __traits(getBitfieldOffset,T.tupleof[i+1]))
{
enum el = (i > 0 ? separator : "") ~ "#{overlap " ~ __traits(identifier, T.tupleof[i]);
put(w, el);
Expand Down
Loading