@@ -7114,8 +7114,8 @@ private extern(C++) class SetFieldOffsetVisitor : Visitor
7114
7114
7115
7115
const sz = t.size(vd.loc);
7116
7116
assert (sz != SIZE_INVALID && sz < uint .max);
7117
- uint memsize = cast (uint )sz; // size of member
7118
- uint memalignsize = target.fieldalign(t); // size of member for alignment purposes
7117
+ const memsize = cast (uint )sz; // size of member
7118
+ const memalignsize = target.fieldalign(t); // size of member for alignment purposes
7119
7119
vd.offset = placeField(vd.loc,
7120
7120
fieldState.offset,
7121
7121
memsize, memalignsize, vd.alignment,
@@ -7153,8 +7153,8 @@ private extern(C++) class SetFieldOffsetVisitor : Visitor
7153
7153
7154
7154
const sz = t.size(bfd.loc);
7155
7155
assert (sz != SIZE_INVALID && sz < uint .max);
7156
- uint memsize = cast (uint )sz; // size of member
7157
- uint memalignsize = target.fieldalign(t); // size of member for alignment purposes
7156
+ const uint memsize = cast (uint )sz; // size of member
7157
+ const uint memalignsize = target.fieldalign(t); // size of member for alignment purposes
7158
7158
if (log) printf(" memsize: %u memalignsize: %u\n " , memsize, memalignsize);
7159
7159
7160
7160
if (bfd.fieldWidth == 0 && ! anon)
@@ -7169,6 +7169,12 @@ private extern(C++) class SetFieldOffsetVisitor : Visitor
7169
7169
const isMicrosoftStyle = style == TargetC.BitFieldStyle.MS ;
7170
7170
const contributesToAggregateAlignment = target.c.contributesToAggregateAlignment(bfd);
7171
7171
7172
+ /* Flag bitfield non-portable layouts that differ between MicrosoftStyle and non-MicrosoftStyle
7173
+ * unless it's C semantics.
7174
+ */
7175
+ const checkPortable = false ; // !sc.inCfile && sc.linkage == LINK.d;
7176
+ bool isPortable = true ; // start out assuming portable
7177
+
7172
7178
void startNewField ()
7173
7179
{
7174
7180
if (log) printf(" startNewField()\n " );
@@ -7208,19 +7214,16 @@ private extern(C++) class SetFieldOffsetVisitor : Visitor
7208
7214
7209
7215
if (bfd.fieldWidth == 0 )
7210
7216
{
7211
- if (! isMicrosoftStyle && ! isunion)
7217
+ if (! isunion)
7212
7218
{
7213
- // Use type of zero width field to align to next field
7214
- fieldState.offset = (fieldState.offset + memalignsize - 1 ) & ~ (memalignsize - 1 );
7215
- ad.structsize = fieldState.offset;
7216
- }
7217
- else if (isMicrosoftStyle && fieldState.inFlight && ! isunion)
7218
- {
7219
- // documentation says align to next int
7220
- // const alsz = cast(uint)Type.tint32.size();
7221
- const alsz = memsize; // but it really does this
7222
- fieldState.offset = (fieldState.offset + alsz - 1 ) & ~ (alsz - 1 );
7223
- ad.structsize = fieldState.offset;
7219
+ if (! isMicrosoftStyle || fieldState.inFlight)
7220
+ {
7221
+ const alsz = isMicrosoftStyle
7222
+ ? memsize // documentation says align to next int but memsize is actually used
7223
+ : memalignsize; // use type of zero width field to align to next field
7224
+ fieldState.offset = (fieldState.offset + alsz - 1 ) & ~ (alsz - 1 );
7225
+ ad.structsize = fieldState.offset;
7226
+ }
7224
7227
}
7225
7228
7226
7229
fieldState.inFlight = false ;
@@ -7229,7 +7232,7 @@ private extern(C++) class SetFieldOffsetVisitor : Visitor
7229
7232
7230
7233
if (! fieldState.inFlight)
7231
7234
{
7232
- // printf("not in flight\n");
7235
+ if (log) printf(" not in flight\n " );
7233
7236
startNewField();
7234
7237
}
7235
7238
else if (! isMicrosoftStyle)
@@ -7296,6 +7299,11 @@ private extern(C++) class SetFieldOffsetVisitor : Visitor
7296
7299
fieldState.bitOffset = pastField;
7297
7300
}
7298
7301
7302
+ if (checkPortable && ! isPortable)
7303
+ {
7304
+ error(bfd.loc, " bitfield layout not portable among supported C compilers, wrap with `extern (C)` or `extern (C++)`" );
7305
+ }
7306
+
7299
7307
// printf("\t%s: offset = %d bitOffset = %d fieldWidth = %d memsize = %d\n", toChars(), offset, bitOffset, fieldWidth, memsize);
7300
7308
// printf("\t%s: memalignsize = %d\n", toChars(), memalignsize);
7301
7309
// printf(" addField '%s' to '%s' at offset %d, size = %d\n", toChars(), ad.toChars(), offset, memsize);
0 commit comments