aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmine Najahi <mohaminaj@gmail.com>2013-10-06 14:43:16 +0200
committerAmine Najahi <mohaminaj@gmail.com>2013-10-06 14:51:29 +0200
commit3b07a15fd12d5452bf539cd855edde8139db1686 (patch)
treed35e02afb9539566893e4e09cee83c9a4886ac2b
parentd0c2f00df2366ba2114c75ada95c578864a81387 (diff)
downloadtinycc-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
-rw-r--r--tccgen.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/tccgen.c b/tccgen.c
index d5b915b..bab4f7c 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -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'",