diff --git a/parse.c b/parse.c index 1d6c94b91b99813660553d27b2c4dd4269bfc4a9..633bf97f79ebd17aeb9e623a4dbf3d616b30238f 100644 --- a/parse.c +++ b/parse.c @@ -2134,7 +2134,11 @@ static Type *struct_decl(Token **rest, Token *tok) { int bits = 0; for (Member *mem = ty->members; mem; mem = mem->next) { - if (mem->is_bitfield) { + if (mem->is_bitfield && mem->bit_width == 0) { + // Zero-width anonymous bitfield has a special meaning. + // It affects only alignment. + bits = align_to(bits, mem->ty->size * 8); + } else if (mem->is_bitfield) { int sz = mem->ty->size; if (bits / (sz * 8) != (bits + mem->bit_width - 1) / (sz * 8)) bits = align_to(bits, sz * 8); diff --git a/test/bitfield.c b/test/bitfield.c index 08f64ff94e0bcea343457219929cea3ab7febcc9..169081c4e2642b38a96538a7321abdb485060f1c 100644 --- a/test/bitfield.c +++ b/test/bitfield.c @@ -48,6 +48,10 @@ int main() { ASSERT(3, ({ T3 x={1,2,3}; ++x.b; })); ASSERT(4, ({ T3 x={1,2,3}; ++x.c; })); + ASSERT(4, sizeof(struct {int a:3; int c:1; int c:5;})); + ASSERT(8, sizeof(struct {int a:3; int:0; int c:5;})); + ASSERT(4, sizeof(struct {int a:3; int:0;})); + printf("OK\n"); return 0; }