aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Forney <mforney@mforney.org>2021-07-01 01:34:00 -0700
committerMichael Forney <mforney@mforney.org>2021-07-01 01:52:13 -0700
commiteb4320fcc6caf885038fe8b7b7d33ed87eb56608 (patch)
tree6e6c5afef7646c48be2bc5e57bbfbd9b8ce4c454
parentb2dc1102c3ae0976e9435f80df660b821742a2c8 (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.c4
-rw-r--r--test/struct-flexible-array.c10
-rw-r--r--test/struct-flexible-array.qbe19
3 files changed, 32 insertions, 1 deletions
diff --git a/decl.c b/decl.c
index d9e2a85..8912c6a 100644
--- a/decl.c
+++ b/decl.c
@@ -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
+}