Skip to content

Commit a2ddee1

Browse files
committed
decl: Allow union specifiers to contain structs/unions with flexible array members
Thanks to Thorsten Glaser for reporting this issue. Fixes #91.
1 parent da58ac4 commit a2ddee1

File tree

3 files changed

+44
-3
lines changed

3 files changed

+44
-3
lines changed

decl.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -744,19 +744,22 @@ addmember(struct structbuilder *b, struct qualtype mt, char *name, int align, un
744744
struct member *m;
745745
size_t end;
746746

747-
if (t->flexible)
747+
if (t->kind == TYPESTRUCT && t->flexible)
748748
error(&tok.loc, "struct has member '%s' after flexible array member", name);
749749
if (mt.type->incomplete) {
750750
if (mt.type->kind != TYPEARRAY)
751751
error(&tok.loc, "struct member '%s' has incomplete type", name);
752752
t->flexible = true;
753753
}
754+
if (mt.type->flexible) {
755+
if (t->kind == TYPESTRUCT)
756+
error(&tok.loc, "struct member '%s' contains flexible array member", name);
757+
t->flexible = true;
758+
}
754759
if (mt.type->kind == TYPEFUNC)
755760
error(&tok.loc, "struct member '%s' has function type", name);
756761
if (mt.type->prop & PROPVM)
757762
error(&tok.loc, "struct member '%s' has variably modified type", name);
758-
if (mt.type->flexible)
759-
error(&tok.loc, "struct member '%s' contains flexible array member", name);
760763
assert(mt.type->align > 0);
761764
if (name || width == -1) {
762765
m = xmalloc(sizeof(*m));

test/union-struct-flexible-array.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
union u {
2+
struct {
3+
int a;
4+
short b[];
5+
} s;
6+
unsigned char storage[32];
7+
};
8+
9+
int x = sizeof(union u);
10+
11+
int f(union u *u) {
12+
return u->s.b[2] + u->storage[0];
13+
}

test/union-struct-flexible-array.qbe

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
export data $x = align 4 { w 32, }
2+
export
3+
function w $f(l %.1) {
4+
@start.1
5+
%.2 =l alloc8 8
6+
storel %.1, %.2
7+
@body.2
8+
%.3 =l loadl %.2
9+
%.4 =l add %.3, 0
10+
%.5 =l add %.4, 4
11+
%.6 =l extsw 2
12+
%.7 =l mul %.6, 2
13+
%.8 =l add %.5, %.7
14+
%.9 =w loadsh %.8
15+
%.10 =w extsh %.9
16+
%.11 =l loadl %.2
17+
%.12 =l add %.11, 0
18+
%.13 =l extsw 0
19+
%.14 =l mul %.13, 1
20+
%.15 =l add %.12, %.14
21+
%.16 =w loadub %.15
22+
%.17 =w extub %.16
23+
%.18 =w add %.10, %.17
24+
ret %.18
25+
}

0 commit comments

Comments
 (0)