| @@ -3285,6 +3285,9 @@ static void struct_layout(CType *type, AttributeDef *ad) · 3284 unmodified lines |
| 3285 | { | 3285 | { |
| 3286 | int align, maxalign, offset, c, bit_pos, bt, prevbt, prev_bit_size; | 3286 | int align, maxalign, offset, c, bit_pos, bt, prevbt, prev_bit_size; |
| 3287 | int pcc = !tcc_state->ms_bitfields; | 3287 | int pcc = !tcc_state->ms_bitfields; |
| | 3288 | int packwarn = tcc_state->warn_gcc_compat; |
| | 3289 | int typealign, bit_size, size; |
| | 3290 | |
| 3288 | Sym *f; | 3291 | Sym *f; |
| 3289 | if (ad->a.aligned) | 3292 | if (ad->a.aligned) |
| 3290 | maxalign = 1 << (ad->a.aligned - 1); | 3293 | maxalign = 1 << (ad->a.aligned - 1); |
| @@ -3295,9 +3298,10 @@ static void struct_layout(CType *type, AttributeDef *ad) · 4 unmodified lines |
| 3295 | bit_pos = 0; | 3298 | bit_pos = 0; |
| 3296 | prevbt = VT_STRUCT; /* make it never match */ | 3299 | prevbt = VT_STRUCT; /* make it never match */ |
| 3297 | prev_bit_size = 0; | 3300 | prev_bit_size = 0; |
| | 3301 | size = 0; |
| | 3302 | |
| 3298 | for (f = type->ref->next; f; f = f->next) { | 3303 | for (f = type->ref->next; f; f = f->next) { |
| 3299 | int typealign, bit_size; | 3304 | size = type_size(&f->type, &typealign); |
| 3300 | int size = type_size(&f->type, &typealign); | | |
| 3301 | if (f->type.t & VT_BITFIELD) | 3305 | if (f->type.t & VT_BITFIELD) |
| 3302 | bit_size = (f->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f; | 3306 | bit_size = (f->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f; |
| 3303 | else | 3307 | else |
| @@ -3358,13 +3362,20 @@ static void struct_layout(CType *type, AttributeDef *ad) · 54 unmodified lines |
| 3358 | int ofs = (c * 8 + bit_pos) % (typealign * 8); | 3362 | int ofs = (c * 8 + bit_pos) % (typealign * 8); |
| 3359 | int ofs2 = ofs + bit_size + (typealign * 8) - 1; | 3363 | int ofs2 = ofs + bit_size + (typealign * 8) - 1; |
| 3360 | if (bit_size == 0 || | 3364 | if (bit_size == 0 || |
| 3361 | ((typealign != 1 || size == 1) && | 3365 | (typealign != 1 && |
| 3362 | (ofs2 / (typealign * 8)) > (size/typealign))) { | 3366 | (ofs2 / (typealign * 8)) > (size/typealign))) { |
| 3363 | c = (c + ((bit_pos + 7) >> 3) + typealign - 1) & -typealign; | 3367 | c = (c + ((bit_pos + 7) >> 3) + typealign - 1) & -typealign; |
| 3364 | bit_pos = 0; | 3368 | bit_pos = 0; |
| 3365 | } else if (bit_pos + bit_size > size * 8) { | 3369 | } else if (bit_pos + bit_size > size * 8) { |
| 3366 | c += bit_pos >> 3; | 3370 | c += bit_pos >> 3; |
| 3367 | bit_pos &= 7; | 3371 | bit_pos &= 7; |
| | 3372 | if (bit_pos + bit_size > size * 8) { |
| | 3373 | c += 1, bit_pos = 0; |
| | 3374 | if ((ad->a.packed || f->r) && packwarn) { |
| | 3375 | tcc_warning("struct layout not compatible with GCC (internal limitation)"); |
| | 3376 | packwarn = 0; |
| | 3377 | } |
| | 3378 | } |
| 3368 | } | 3379 | } |
| 3369 | offset = c; | 3380 | offset = c; |
| 3370 | /* In PCC layout named bit-fields influence the alignment | 3381 | /* In PCC layout named bit-fields influence the alignment |
| @@ -3407,8 +3418,8 @@ static void struct_layout(CType *type, AttributeDef *ad) · 36 unmodified lines |
| 3407 | if (align > maxalign) | 3418 | if (align > maxalign) |
| 3408 | maxalign = align; | 3419 | maxalign = align; |
| 3409 | #if 0 | 3420 | #if 0 |
| 3410 | printf("set field %s offset=%d c=%d", | 3421 | printf("set field %s offset=%d", |
| 3411 | get_tok_str(f->v & ~SYM_FIELD, NULL), offset, c); | 3422 | get_tok_str(f->v & ~SYM_FIELD, NULL), offset); |
| 3412 | if (f->type.t & VT_BITFIELD) { | 3423 | if (f->type.t & VT_BITFIELD) { |
| 3413 | printf(" pos=%d size=%d", | 3424 | printf(" pos=%d size=%d", |
| 3414 | (f->type.t >> VT_STRUCT_SHIFT) & 0x3f, | 3425 | (f->type.t >> VT_STRUCT_SHIFT) & 0x3f, |
| @@ -3458,6 +3469,8 @@ static void struct_layout(CType *type, AttributeDef *ad) · 43 unmodified lines |
| 3458 | type->ref->c = (c + (pcc ? (bit_pos + 7) >> 3 : 0) | 3469 | type->ref->c = (c + (pcc ? (bit_pos + 7) >> 3 : 0) |
| 3459 | + maxalign - 1) & -maxalign; | 3470 | + maxalign - 1) & -maxalign; |
| 3460 | type->ref->r = maxalign; | 3471 | type->ref->r = maxalign; |
| | 3472 | if (offset + size > type->ref->c) |
| | 3473 | tcc_warning("will touch memory past end of the struct (internal limitation)"); |
| 3461 | } | 3474 | } |
| 3462 | | 3475 | |
| 3463 | /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */ | 3476 | /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */ |
| @@ -3615,7 +3628,7 @@ static void struct_decl(CType *type, AttributeDef *ad, int u) · 151 unmodified lines |
| 3615 | } else if (ad1.a.packed || ad->a.packed) { | 3628 | } else if (ad1.a.packed || ad->a.packed) { |
| 3616 | alignoverride = 1; | 3629 | alignoverride = 1; |
| 3617 | } else if (*tcc_state->pack_stack_ptr) { | 3630 | } else if (*tcc_state->pack_stack_ptr) { |
| 3618 | if (align > *tcc_state->pack_stack_ptr) | 3631 | if (align >= *tcc_state->pack_stack_ptr) |
| 3619 | alignoverride = *tcc_state->pack_stack_ptr; | 3632 | alignoverride = *tcc_state->pack_stack_ptr; |
| 3620 | } | 3633 | } |
| 3621 | if (bit_size >= 0) { | 3634 | if (bit_size >= 0) { |