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 | /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */ | 2740 | /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */ |
| 2741 | static void struct_decl(CType *type, int u, int tdef) | 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 | int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt; | 2744 | int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt; |
| 2745 | Sym *s, *ss, *ass, **ps; | 2745 | Sym *s, *ss, *ass, **ps; |
| 2746 | AttributeDef ad; | 2746 | AttributeDef ad; |
| @@ -2814,9 +2814,13 @@ static void struct_decl(CType *type, int u, int tdef) · 67 unmodified lines | |||
| 2814 | prevbt = VT_INT; | 2814 | prevbt = VT_INT; |
| 2815 | bit_pos = 0; | 2815 | bit_pos = 0; |
| 2816 | offset = 0; | 2816 | offset = 0; |
| 2817 | flexible = 0; | ||
| 2817 | while (tok != '}') { | 2818 | while (tok != '}') { |
| 2818 | parse_btype(&btype, &ad); | 2819 | parse_btype(&btype, &ad); |
| 2819 | while (1) { | 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 | bit_size = -1; | 2824 | bit_size = -1; |
| 2821 | v = 0; | 2825 | v = 0; |
| 2822 | type1 = btype; | 2826 | type1 = btype; |
| @@ -2824,6 +2828,13 @@ static void struct_decl(CType *type, int u, int tdef) · 1 unmodified line | |||
| 2824 | type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT); | 2828 | type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT); |
| 2825 | if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT) | 2829 | if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT) |
| 2826 | expect("identifier"); | 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 | if ((type1.t & VT_BTYPE) == VT_FUNC || | 2838 | if ((type1.t & VT_BTYPE) == VT_FUNC || |
| 2828 | (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE))) | 2839 | (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE))) |
| 2829 | tcc_error("invalid type for '%s'", | 2840 | tcc_error("invalid type for '%s'", |