diff options
author | Michael Forney <mforney@mforney.org> | 2021-07-01 01:34:00 -0700 |
---|---|---|
committer | Michael Forney <mforney@mforney.org> | 2021-07-01 01:52:13 -0700 |
commit | eb4320fcc6caf885038fe8b7b7d33ed87eb56608 (patch) | |
tree | 6e6c5afef7646c48be2bc5e57bbfbd9b8ce4c454 | |
parent | b2dc1102c3ae0976e9435f80df660b821742a2c8 (diff) |
decl: Disallow members with incomplete types
Make an exception for flexible array members, though we should also
check that the flexible array member, if any, is last.
-rw-r--r-- | decl.c | 4 | ||||
-rw-r--r-- | test/struct-flexible-array.c | 10 | ||||
-rw-r--r-- | test/struct-flexible-array.qbe | 19 |
3 files changed, 32 insertions, 1 deletions
@@ -685,7 +685,9 @@ addmember(struct structbuilder *b, struct qualtype mt, char *name, int align, ui struct member *m; size_t end; - // XXX: check incomplete type, except for flexible array member + /* 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 (mt.type->kind == TYPEFUNC) error(&tok.loc, "struct member '%s' has function type", name); assert(mt.type->align > 0); diff --git a/test/struct-flexible-array.c b/test/struct-flexible-array.c new file mode 100644 index 0000000..57bd95a --- /dev/null +++ b/test/struct-flexible-array.c @@ -0,0 +1,10 @@ +struct s { + int a; + short b[]; +}; + +int x = sizeof(struct s); + +int f(struct s *s) { + return s->b[2]; +} diff --git a/test/struct-flexible-array.qbe b/test/struct-flexible-array.qbe new file mode 100644 index 0000000..535c5d2 --- /dev/null +++ b/test/struct-flexible-array.qbe @@ -0,0 +1,19 @@ +export data $x = align 4 { w 4, } +export +function w $f(l %.1) { +@start.1 + %.2 =l alloc8 8 + storel %.1, %.2 +@body.2 + %.3 =l loadl %.2 + %.4 =l copy %.3 + %.5 =l mul 4, 1 + %.6 =l add %.4, %.5 + %.7 =l copy %.6 + %.8 =l extsw 2 + %.9 =l mul %.8, 2 + %.10 =l add %.7, %.9 + %.11 =w loadsh %.10 + %.12 =w extsh %.11 + ret %.12 +} |