@@ -2546,9 +2546,23 @@ if ((is(T == struct) || is(T == union)) && (hasToString!(T, Char) || !is(Builtin
25462546 {
25472547 // ignore hidden context pointer
25482548 }
2549- else static if (0 < i && T.tupleof[i- 1 ].offsetof == T.tupleof[i].offsetof)
2549+ /* https://github.com/dlang/phobos/issues/10840
2550+ * handle possible bitfields by doing overlap comparisons
2551+ * using bit counts rather than byte counts.
2552+ * However, the overlap
2553+ * check in general does not take into account staggered unions.
2554+ * This can be fixed using the correct algorithm implemented in
2555+ * the compiler function dmd.declaration.isOverlappedWith().
2556+ * For the moment we will not change to that because the `#(overlap ...)` output
2557+ * needs to be re-thought, as it was never correct.
2558+ */
2559+ else static if (0 < i &&
2560+ T.tupleof[i- 1 ].offsetof * 8 + __traits(getBitfieldOffset,T.tupleof[i- 1 ]) ==
2561+ T.tupleof[i ].offsetof * 8 + __traits(getBitfieldOffset,T.tupleof[i ]))
25502562 {
2551- static if (i == T.tupleof.length - 1 || T.tupleof[i].offsetof != T.tupleof[i+ 1 ].offsetof)
2563+ static if (i == T.tupleof.length - 1 ||
2564+ T.tupleof[i ].offsetof * 8 + __traits(getBitfieldOffset,T.tupleof[i ]) !=
2565+ T.tupleof[i+ 1 ].offsetof * 8 + __traits(getBitfieldOffset,T.tupleof[i+ 1 ]))
25522566 {
25532567 enum el = separator ~ __traits(identifier, T.tupleof[i]) ~ " }" ;
25542568 put(w, el);
@@ -2559,7 +2573,9 @@ if ((is(T == struct) || is(T == union)) && (hasToString!(T, Char) || !is(Builtin
25592573 put(w, el);
25602574 }
25612575 }
2562- else static if (i+ 1 < T.tupleof.length && T.tupleof[i].offsetof == T.tupleof[i+ 1 ].offsetof)
2576+ else static if (i+ 1 < T.tupleof.length &&
2577+ T.tupleof[i ].offsetof * 8 + __traits(getBitfieldOffset,T.tupleof[i ]) ==
2578+ T.tupleof[i+ 1 ].offsetof * 8 + __traits(getBitfieldOffset,T.tupleof[i+ 1 ]))
25632579 {
25642580 enum el = (i > 0 ? separator : " " ) ~ " #{overlap " ~ __traits(identifier, T.tupleof[i]);
25652581 put(w, el);
0 commit comments