diff options
| author | Amine Najahi <mohaminaj@gmail.com> | 2013-10-06 14:43:16 +0200 |
|---|---|---|
| committer | Amine Najahi <mohaminaj@gmail.com> | 2013-10-06 14:51:29 +0200 |
| commit | 3b07a15fd12d5452bf539cd855edde8139db1686 (patch) | |
| tree | d35e02afb9539566893e4e09cee83c9a4886ac2b /tccgen.c | |
| parent | d0c2f00df2366ba2114c75ada95c578864a81387 (diff) | |
| download | tinycc-3b07a15fd12d5452bf539cd855edde8139db1686.tar.gz tinycc-3b07a15fd12d5452bf539cd855edde8139db1686.tar.bz2 | |
Detect usage of incomplete types inside struct/union
Make sure the only exception is for a flexible array member
as the last element of a structure
Diffstat (limited to 'tccgen.c')
| -rw-r--r-- | tccgen.c | 13 |
1 files changed, 12 insertions, 1 deletions
@@ -2740,7 +2740,7 @@ static void parse_attribute(AttributeDef *ad) /* enum/struct/union declaration. u is either VT_ENUM or VT_STRUCT */ static void struct_decl(CType *type, int u, int tdef) { - int a, v, size, align, maxalign, c, offset; + int a, v, size, align, maxalign, c, offset, flexible; int bit_size, bit_pos, bsize, bt, lbit_pos, prevbt; Sym *s, *ss, *ass, **ps; AttributeDef ad; @@ -2814,9 +2814,13 @@ static void struct_decl(CType *type, int u, int tdef) prevbt = VT_INT; bit_pos = 0; offset = 0; + flexible = 0; while (tok != '}') { parse_btype(&btype, &ad); while (1) { + if (flexible) + tcc_error("flexible array member '%s' not at the end of struct", + get_tok_str(v, NULL)); bit_size = -1; v = 0; type1 = btype; @@ -2824,6 +2828,13 @@ static void struct_decl(CType *type, int u, int tdef) type_decl(&type1, &ad, &v, TYPE_DIRECT | TYPE_ABSTRACT); if (v == 0 && (type1.t & VT_BTYPE) != VT_STRUCT) expect("identifier"); + if (type_size(&type1, &align) < 0) { + if ((a == TOK_STRUCT) && (type1.t & VT_ARRAY) && c) + flexible = 1; + else + tcc_error("field '%s' has incomplete type", + get_tok_str(v, NULL)); + } if ((type1.t & VT_BTYPE) == VT_FUNC || (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE))) tcc_error("invalid type for '%s'", |
