Make sure the only exception is for a flexible array member as the last element of a structure
Unified · Split
| @@ -2740,7 +2740,7 @@ static void parse_attribute(AttributeDef *ad) · 2739 unmodified lines | ||
| 2740 | 2740 | /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */ |
| 2741 | 2741 | static void struct_decl(CType *type, int u, int tdef) |
| 2742 | 2742 | { |
| 2743 | − int a, v, size, align, maxalign, c, offset; | |
| 2743 | + int a, v, size, align, maxalign, c, offset, flexible; | |
| 2744 | 2744 | int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt; |
| 2745 | 2745 | Sym *s, *ss, *ass, **ps; |
| 2746 | 2746 | AttributeDef ad; |
| @@ -2814,9 +2814,13 @@ static void struct_decl(CType *type, int u, int tdef) · 67 unmodified lines | ||
| 2814 | 2814 | prevbt = VT_INT; |
| 2815 | 2815 | bit_pos = 0; |
| 2816 | 2816 | offset = 0; |
| 2817 | + flexible = 0; | |
| 2817 | 2818 | while (tok != '}') { |
| 2818 | 2819 | parse_btype(&btype, &ad); |
| 2819 | 2820 | while (1) { |
| 2821 | + if (flexible) | |
| 2822 | + tcc_error("flexible array member '%s' not at the end of struct", | |
| 2823 | + get_tok_str(v, NULL)); | |
| 2820 | 2824 | bit_size = -1; |
| 2821 | 2825 | v = 0; |
| 2822 | 2826 | type1 = btype; |
| @@ -2824,6 +2828,13 @@ static void struct_decl(CType *type, int u, int tdef) · 1 unmodified line | ||
| 2824 | 2828 | type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT); |
| 2825 | 2829 | if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT) |
| 2826 | 2830 | expect("identifier"); |
| 2831 | + if (type_size(&type1, &align) < 0) { | |
| 2832 | + if ((a == TOK_STRUCT) && (type1.t & VT_ARRAY) && c) | |
| 2833 | + flexible = 1; | |
| 2834 | + else | |
| 2835 | + tcc_error("field '%s' has incomplete type", | |
| 2836 | + get_tok_str(v, NULL)); | |
| 2837 | + } | |
| 2827 | 2838 | if ((type1.t & VT_BTYPE) == VT_FUNC || |
| 2828 | 2839 | (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE))) |
| 2829 | 2840 | tcc_error("invalid type for '%s'", |