This replaces commit 5c6356ff8e8ad57c8d5ad8220d665dfba02290cf, except the tests.
Unified · Split
| @@ -7423,10 +7423,17 @@ static int decl_designator(CType *type, Section *sec, unsigned long c, · 7422 unmodified lines | |||
| 7423 | c += f->c; | 7423 | c += f->c; |
| 7424 | } | 7424 | } |
| 7425 | } | 7425 | } |
| 7426 | |||
| 7426 | /* must put zero in holes (note that doing it that way | 7427 | /* must put zero in holes (note that doing it that way |
| 7427 | ensures that it even works with designators) */ | 7428 | ensures that it even works with designators) */ |
| 7428 | if (!(flags & DIF_SIZE_ONLY) && c - corig > al) | 7429 | if (!(flags & DIF_SIZE_ONLY)) { |
| 7429 | init_putz(sec, corig + al, c - corig - al); | 7430 | int zlen = c - (corig + al); |
| 7431 | if (type->t & VT_BITFIELD) /* must include current field too */ | ||
| 7432 | zlen += type_size(type, &align); | ||
| 7433 | if (zlen > 0) | ||
| 7434 | init_putz(sec, corig + al, zlen); | ||
| 7435 | } | ||
| 7436 | |||
| 7430 | decl_initializer(type, sec, c, flags & ~DIF_FIRST); | 7437 | decl_initializer(type, sec, c, flags & ~DIF_FIRST); |
| 7431 | 7438 | ||
| 7432 | /* XXX: make it more general */ | 7439 | /* XXX: make it more general */ |
| @@ -7651,23 +7658,6 @@ static void init_putv(CType *type, Section *sec, unsigned long c) · 218 unmodified lines | |||
| 7651 | } | 7658 | } |
| 7652 | } | 7659 | } |
| 7653 | 7660 | ||
| 7654 | /* Check for bitfield in struct/union recursive */ | ||
| 7655 | static int check_bf(Sym *f) | ||
| 7656 | { | ||
| 7657 | while (f->next) { | ||
| 7658 | f = f->next; | ||
| 7659 | if ((f->type.t & VT_BITFIELD) || | ||
| 7660 | ((f->type.t & VT_BTYPE) == VT_STRUCT && check_bf(f->type.ref))) | ||
| 7661 | return 1; | ||
| 7662 | if (f->type.t & VT_ARRAY) { | ||
| 7663 | Sym *r = f->type.ref; | ||
| 7664 | if (((r->type.t & VT_BTYPE) == VT_STRUCT && check_bf(r->type.ref))) | ||
| 7665 | return 1; | ||
| 7666 | } | ||
| 7667 | } | ||
| 7668 | return 0; | ||
| 7669 | } | ||
| 7670 | |||
| 7671 | /* 't' contains the type and storage info. 'c' is the offset of the | 7661 | /* 't' contains the type and storage info. 'c' is the offset of the |
| 7672 | object in section 'sec'. If 'sec' is NULL, it means stack based | 7662 | object in section 'sec'. If 'sec' is NULL, it means stack based |
| 7673 | allocation. 'flags & DIF_FIRST' is true if array '{' must be read (multi | 7663 | allocation. 'flags & DIF_FIRST' is true if array '{' must be read (multi |
| @@ -7705,11 +7695,6 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 31 unmodified lines | |||
| 7705 | t1 = pointed_type(type); | 7695 | t1 = pointed_type(type); |
| 7706 | size1 = type_size(t1, &align1); | 7696 | size1 = type_size(t1, &align1); |
| 7707 | 7697 | ||
| 7708 | if (!(flags & DIF_SIZE_ONLY) && | ||
| 7709 | (s->type.t & VT_BTYPE) == VT_STRUCT && check_bf (s->type.ref)) | ||
| 7710 | /* If there is a bitfield in array clear it */ | ||
| 7711 | init_putz(sec, c, size1 * n); | ||
| 7712 | |||
| 7713 | no_oblock = 1; | 7698 | no_oblock = 1; |
| 7714 | if (((flags & DIF_FIRST) && tok != TOK_LSTR && tok != TOK_STR) || | 7699 | if (((flags & DIF_FIRST) && tok != TOK_LSTR && tok != TOK_STR) || |
| 7715 | tok == '{') { | 7700 | tok == '{') { |
| @@ -7839,9 +7824,6 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 123 unmodified lines | |||
| 7839 | s = type->ref; | 7824 | s = type->ref; |
| 7840 | f = s->next; | 7825 | f = s->next; |
| 7841 | n = s->c; | 7826 | n = s->c; |
| 7842 | if (!(flags & DIF_SIZE_ONLY) && check_bf (s)) | ||
| 7843 | /* If there is a bitfield in struct/union clear it */ | ||
| 7844 | init_putz(sec, c, n); | ||
| 7845 | goto do_init_list; | 7827 | goto do_init_list; |
| 7846 | } else if (tok == '{') { | 7828 | } else if (tok == '{') { |
| 7847 | if (flags & DIF_HAVE_ELEM) | 7829 | if (flags & DIF_HAVE_ELEM) |