Fixes some corner cases in PCC layout. Testcases coming up.
Unified · Split
| @@ -3267,6 +3267,7 @@ static void struct_add_offset (Sym *s, int offset) · 3266 unmodified lines | ||
| 3267 | 3267 | static void struct_layout(CType *type, AttributeDef *ad) |
| 3268 | 3268 | { |
| 3269 | 3269 | int align, maxalign, offset, c, bit_pos, bt, prevbt; |
| 3270 | + int pcc = !tcc_state->ms_bitfields; | |
| 3270 | 3271 | Sym *f; |
| 3271 | 3272 | if (ad->a.aligned) |
| 3272 | 3273 | maxalign = ad->a.aligned; |
| @@ -3280,13 +3281,12 @@ static void struct_layout(CType *type, AttributeDef *ad) · 7 unmodified lines | ||
| 3280 | 3281 | int extra_bytes = 0; |
| 3281 | 3282 | int typealign, bit_size; |
| 3282 | 3283 | int size = type_size(&f->type, &typealign); |
| 3283 | − int pcc = !tcc_state->ms_bitfields; | |
| 3284 | 3284 | if (f->type.t & VT_BITFIELD) { |
| 3285 | 3285 | bit_size = (f->type.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f; |
| 3286 | 3286 | /* without ms-bitfields, allocate the |
| 3287 | 3287 | * minimum number of bytes necessary, |
| 3288 | 3288 | * adding single bytes as needed */ |
| 3289 | − if (!tcc_state->ms_bitfields) { | |
| 3289 | + if (0 && !tcc_state->ms_bitfields) { | |
| 3290 | 3290 | if (bit_pos == 0) |
| 3291 | 3291 | /* minimum bytes for new bitfield */ |
| 3292 | 3292 | size = (bit_size + 7) / 8; |
| @@ -3311,55 +3311,59 @@ static void struct_layout(CType *type, AttributeDef *ad) · 18 unmodified lines | ||
| 3311 | 3311 | } else { |
| 3312 | 3312 | align = typealign; |
| 3313 | 3313 | } |
| 3314 | − /*if (extra_bytes) c += extra_bytes; | |
| 3315 | − else*/ if (bit_size < 0) { | |
| 3316 | − int addbytes = pcc ? (bit_pos + 7) >> 3 : 0; | |
| 3314 | + if (extra_bytes) c += extra_bytes; | |
| 3315 | + else if (bit_size < 0) { | |
| 3316 | + prevbt = VT_STRUCT; | |
| 3317 | 3317 | if (type->ref->type.t == TOK_STRUCT) { |
| 3318 | + int addbytes = pcc ? (bit_pos + 7) >> 3 : 0; | |
| 3318 | 3319 | c = (c + addbytes + align - 1) & -align; |
| 3319 | 3320 | offset = c; |
| 3320 | 3321 | if (size > 0) |
| 3321 | 3322 | c += size; |
| 3322 | 3323 | } else { |
| 3324 | + union_tail: | |
| 3323 | 3325 | offset = 0; |
| 3324 | − if (addbytes > c) | |
| 3325 | − c = addbytes; | |
| 3326 | 3326 | if (size > c) |
| 3327 | 3327 | c = size; |
| 3328 | 3328 | } |
| 3329 | 3329 | if (align > maxalign) |
| 3330 | 3330 | maxalign = align; |
| 3331 | 3331 | bit_pos = 0; |
| 3332 | − prevbt = VT_STRUCT; | |
| 3332 | + } else if (type->ref->type.t != TOK_STRUCT) { | |
| 3333 | + if (pcc) | |
| 3334 | + size = (bit_size + 7) >> 3; | |
| 3335 | + f->type.t = (f->type.t & ~(0x3f << VT_STRUCT_SHIFT)) | |
| 3336 | + | (0 << VT_STRUCT_SHIFT); | |
| 3337 | + goto union_tail; | |
| 3333 | 3338 | } else { |
| 3334 | 3339 | /* A bit-field. Layout is more complicated. There are two |
| 3335 | 3340 | options TCC implements: PCC compatible and MS compatible |
| 3336 | 3341 | (PCC compatible is what GCC uses for almost all targets). */ |
| 3337 | − if (!bit_pos) { | |
| 3338 | − if (type->ref->type.t == TOK_STRUCT) { | |
| 3339 | − /* Don't align c here. That's only to be done | |
| 3340 | − in certain cases. */ | |
| 3341 | − offset = c; | |
| 3342 | − } else { | |
| 3343 | − offset = 0; | |
| 3344 | − } | |
| 3345 | − } | |
| 3346 | 3342 | if (pcc) { |
| 3347 | 3343 | /* In PCC layout a non-packed bit-field is placed adjacent |
| 3348 | 3344 | to the preceding bit-fields, except if it would overflow |
| 3349 | 3345 | its container (depending on base type) or it's a zero-width |
| 3350 | 3346 | bit-field. Packed non-zero-width bit-fields always are |
| 3351 | 3347 | placed adjacent. */ |
| 3352 | − if ((typealign != 1 && | |
| 3353 | − bit_pos + bit_size > size * 8) || | |
| 3354 | − bit_size == 0) { | |
| 3348 | + int ofs = (c * 8 + bit_pos) % (typealign * 8); | |
| 3349 | + int ofs2 = ofs + bit_size + (typealign * 8) - 1; | |
| 3350 | + /*if ((typealign != 1 && | |
| 3351 | + //bit_pos + bit_size > size * 8) || | |
| 3352 | + (((c + ((bit_pos + 7) >> 3) + typealign - 1) & -typealign) | |
| 3353 | + != ((c + ((bit_pos + bit_size + 7) >> 3) + typealign - 1) & -typealign))) || | |
| 3354 | + bit_size == 0 || | |
| 3355 | + (bit_pos + bit_size > size * 8) | |
| 3356 | + ) {*/ | |
| 3357 | + if (bit_size == 0 || | |
| 3358 | + (typealign != 1 && (ofs2 / (typealign * 8)) > ((size*8)/(typealign*8)))) { | |
| 3355 | 3359 | c = (c + ((bit_pos + 7) >> 3) + typealign - 1) & -typealign; |
| 3356 | − offset = c; | |
| 3357 | 3360 | bit_pos = 0; |
| 3358 | 3361 | } |
| 3362 | + offset = c; | |
| 3359 | 3363 | /* In PCC layout named bit-fields influence the alignment |
| 3360 | 3364 | of the containing struct using the base types alignment, |
| 3361 | 3365 | except for packed fields or zero-width fields. */ |
| 3362 | − if (bit_size > 0) { | |
| 3366 | + if (!(f->v & SYM_FIRST_ANOM)) { | |
| 3363 | 3367 | if (align > maxalign) |
| 3364 | 3368 | maxalign = align; |
| 3365 | 3369 | if (typealign > maxalign) |
| @@ -3444,7 +3448,8 @@ static void struct_layout(CType *type, AttributeDef *ad) · 78 unmodified lines | ||
| 3444 | 3448 | f->r = 0; |
| 3445 | 3449 | } |
| 3446 | 3450 | /* store size and alignment */ |
| 3447 | − type->ref->c = (c + ((bit_pos + 7) >> 3) + maxalign - 1) & -maxalign; | |
| 3451 | + type->ref->c = (c + (pcc ? (bit_pos + 7) >> 3 : 0) | |
| 3452 | + + maxalign - 1) & -maxalign; | |
| 3448 | 3453 | type->ref->r = maxalign; |
| 3449 | 3454 | } |
| 3450 | 3455 | |