aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cc.h2
-rw-r--r--decl.c12
-rw-r--r--type.c3
3 files changed, 12 insertions, 5 deletions
diff --git a/cc.h b/cc.h
index 774c951..87d4460 100644
--- a/cc.h
+++ b/cc.h
@@ -209,7 +209,7 @@ struct type {
};
/* qualifiers of the base type */
enum typequal qual;
- _Bool incomplete;
+ _Bool incomplete, flexible;
union {
struct {
_Bool issigned, iscomplex;
diff --git a/decl.c b/decl.c
index 8912c6a..7460d04 100644
--- a/decl.c
+++ b/decl.c
@@ -685,11 +685,17 @@ addmember(struct structbuilder *b, struct qualtype mt, char *name, int align, ui
struct member *m;
size_t end;
- /* XXX: flexible array member must be last */
- if (mt.type->incomplete && mt.type->kind != TYPEARRAY)
- error(&tok.loc, "struct member '%s' has incomplete type", name);
+ if (t->flexible)
+ error(&tok.loc, "struct member '%s' is after flexible array member", name);
+ if (mt.type->incomplete) {
+ if (mt.type->kind != TYPEARRAY)
+ error(&tok.loc, "struct member '%s' has incomplete type", name);
+ t->flexible = true;
+ }
if (mt.type->kind == TYPEFUNC)
error(&tok.loc, "struct member '%s' has function type", name);
+ if (mt.type->flexible)
+ error(&tok.loc, "struct member '%s' contains flexible array member", name);
assert(mt.type->align > 0);
if (name || width == -1) {
m = xmalloc(sizeof(*m));
diff --git a/type.c b/type.c
index 1c6888f..39f656f 100644
--- a/type.c
+++ b/type.c
@@ -61,7 +61,8 @@ mktype(enum typekind kind, enum typeprop prop)
t->kind = kind;
t->prop = prop;
t->value = NULL;
- t->incomplete = 0;
+ t->incomplete = false;
+ t->flexible = false;
return t;
}