Skip to content

Commit f17f6be

Browse files
committed
Fix segfault (null deref) in named initialisation of nested anonymous unions
1 parent 90d1f7f commit f17f6be

File tree

2 files changed

+30
-7
lines changed

2 files changed

+30
-7
lines changed

parse.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,10 +1003,11 @@ static Member *struct_designator(Token **rest, Token *tok, Type *ty) {
10031003

10041004
for (Member *mem = ty->members; mem; mem = mem->next) {
10051005
// Anonymous struct member
1006-
if (mem->ty->kind == TY_STRUCT && !mem->name) {
1007-
if (get_struct_member(mem->ty, tok)) {
1008-
*rest = start;
1009-
return mem;
1006+
if (!mem->name) {
1007+
if ((mem->ty->kind == TY_STRUCT || mem->ty->kind == TY_UNION)
1008+
&& get_struct_member(mem->ty, tok)) {
1009+
*rest = start;
1010+
return mem;
10101011
}
10111012
continue;
10121013
}
@@ -2736,11 +2737,13 @@ static Type *union_decl(Token **rest, Token *tok) {
27362737

27372738
// Find a struct member by name.
27382739
static Member *get_struct_member(Type *ty, Token *tok) {
2740+
assert(ty->kind == TY_STRUCT || ty->kind == TY_UNION);
2741+
27392742
for (Member *mem = ty->members; mem; mem = mem->next) {
27402743
// Anonymous struct member
2741-
if ((mem->ty->kind == TY_STRUCT || mem->ty->kind == TY_UNION) &&
2742-
!mem->name) {
2743-
if (get_struct_member(mem->ty, tok))
2744+
if (!mem->name) {
2745+
if ((mem->ty->kind == TY_STRUCT || mem->ty->kind == TY_UNION) &&
2746+
get_struct_member(mem->ty, tok))
27442747
return mem;
27452748
continue;
27462749
}

test/anon-union-init.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#include "test.h"
2+
3+
struct foo {
4+
int simple;
5+
int : 7;
6+
union {
7+
int anon;
8+
union tagged {
9+
float qux;
10+
long baz;
11+
} named;
12+
};
13+
};
14+
15+
struct foo bar = { .simple = 1, .named.qux = 1.0 };
16+
17+
int main() {
18+
printf("OK\n");
19+
return 0;
20+
}

0 commit comments

Comments
 (0)