| @@ -3285,6 +3285,9 @@ static void struct_layout(CType *type, AttributeDef *ad) · 3284 unmodified lines |
| 3285 | 3285 | { |
| 3286 | 3286 | int align, maxalign, offset, c, bit_pos, bt, prevbt, prev_bit_size; |
| 3287 | 3287 | int pcc = !tcc_state->ms_bitfields; |
| 3288 | + int packwarn = tcc_state->warn_gcc_compat; |
| 3289 | + int typealign, bit_size, size; |
| 3290 | + |
| 3288 | 3291 | Sym *f; |
| 3289 | 3292 | if (ad->a.aligned) |
| 3290 | 3293 | maxalign = 1 << (ad->a.aligned - 1); |
| @@ -3295,9 +3298,10 @@ static void struct_layout(CType *type, AttributeDef *ad) · 4 unmodified lines |
| 3295 | 3298 | bit_pos = 0; |
| 3296 | 3299 | prevbt = VT_STRUCT; /* make it never match */ |
| 3297 | 3300 | prev_bit_size = 0; |
| 3301 | + size = 0; |
| 3302 | + |
| 3298 | 3303 | for (f = type->ref->next; f; f = f->next) { |
| 3299 | | − int typealign, bit_size; |
| 3300 | | − int size = type_size(&f->type, &typealign); |
| 3304 | + size = type_size(&f->type, &typealign); |
| 3301 | 3305 | if (f->type.t & VT_BITFIELD) |
| 3302 | 3306 | bit_size = (f->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f; |
| 3303 | 3307 | else |
| @@ -3358,13 +3362,20 @@ static void struct_layout(CType *type, AttributeDef *ad) · 54 unmodified lines |
| 3358 | 3362 | int ofs = (c * 8 + bit_pos) % (typealign * 8); |
| 3359 | 3363 | int ofs2 = ofs + bit_size + (typealign * 8) - 1; |
| 3360 | 3364 | if (bit_size == 0 || |
| 3361 | | − ((typealign != 1 || size == 1) && |
| 3365 | + (typealign != 1 && |
| 3362 | 3366 | (ofs2 / (typealign * 8)) > (size/typealign))) { |
| 3363 | 3367 | c = (c + ((bit_pos + 7) >> 3) + typealign - 1) & -typealign; |
| 3364 | 3368 | bit_pos = 0; |
| 3365 | 3369 | } else if (bit_pos + bit_size > size * 8) { |
| 3366 | 3370 | c += bit_pos >> 3; |
| 3367 | 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 | 3380 | offset = c; |
| 3370 | 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 | 3418 | if (align > maxalign) |
| 3408 | 3419 | maxalign = align; |
| 3409 | 3420 | #if 0 |
| 3410 | | − printf("set field %s offset=%d c=%d", |
| 3411 | | − get_tok_str(f->v & ~SYM_FIELD, NULL), offset, c); |
| 3421 | + printf("set field %s offset=%d", |
| 3422 | + get_tok_str(f->v & ~SYM_FIELD, NULL), offset); |
| 3412 | 3423 | if (f->type.t & VT_BITFIELD) { |
| 3413 | 3424 | printf(" pos=%d size=%d", |
| 3414 | 3425 | (f->type.t >> VT_STRUCT_SHIFT) & 0x3f, |
| @@ -3458,6 +3469,8 @@ static void struct_layout(CType *type, AttributeDef *ad) · 43 unmodified lines |
| 3458 | 3469 | type->ref->c = (c + (pcc ? (bit_pos + 7) >> 3 : 0) |
| 3459 | 3470 | + maxalign - 1) & -maxalign; |
| 3460 | 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 | 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 | 3628 | } else if (ad1.a.packed || ad->a.packed) { |
| 3616 | 3629 | alignoverride = 1; |
| 3617 | 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 | 3632 | alignoverride = *tcc_state->pack_stack_ptr; |
| 3620 | 3633 | } |
| 3621 | 3634 | if (bit_size >= 0) { |