Fixed the bug that a union type containing a struct with a flexible array member was accepted as a struct member or array element type.

This commit is contained in:
acqn 2023-10-27 23:46:10 +08:00
parent 85e63e99a6
commit 8e45a4c960
4 changed files with 49 additions and 10 deletions

View File

@ -517,7 +517,8 @@ static void CheckArrayElementType (const Type* T)
return;
}
} else {
if (IsTypeStruct (T)) {
/* Elements cannot contain flexible array members themselves */
if (IsClassStruct (T)) {
SymEntry* TagEntry = GetESUTagSym (T);
if (TagEntry && SymHasFlexibleArrayMember (TagEntry)) {
Error ("Invalid use of struct with flexible array member");
@ -1202,9 +1203,7 @@ static SymEntry* ParseStructSpec (const char* Name, unsigned* DSFlags)
if (TagEntry && SymHasFlexibleArrayMember (TagEntry)) {
Field->Flags |= SC_HAVEFAM;
Flags |= SC_HAVEFAM;
if (IsTypeStruct (Decl.Type)) {
Error ("Invalid use of struct with flexible array member");
}
Error ("Invalid use of struct with flexible array member");
}
}

View File

@ -5,7 +5,12 @@ typedef struct x {
int b[]; /* Ok: Flexible array member can be last */
} x;
typedef union u {
int a;
x x; /* Ok: Union member can contain flexible array member */
} u;
struct y {
x x; /* Not ok: Contains flexible array member */
u u; /* Not ok: Contains union that contains flexible array member */
int a;
};

View File

@ -1,9 +1,13 @@
/* Bug #2017 - cc65 erroneously allows arrays of structs with flexible array members */
struct z {
typedef struct x {
int a;
int c;
int b[];
};
int b[]; /* Ok: Flexible array member can be last */
} x;
struct z y[3]; /* Should be an error */
typedef union u {
int a;
x x; /* Ok: Union member can contain flexible array member */
} u;
union u y[3]; /* Should be an error */

31
test/val/fam.c Normal file
View File

@ -0,0 +1,31 @@
/* Bug #2016 and #2017 - flexible array members */
typedef struct {
int a;
int b[]; /* Ok: Flexible array member can be last */
} X;
typedef union {
X x; /* Ok: Contains flexible array member */
int a;
} U;
typedef struct {
struct {
int a;
};
int b[]; /* Ok: Flexible array member can be last */
} Y;
X x;
U u;
Y y;
_Static_assert(sizeof x == sizeof (int), "sizeof x != sizeof (int)");
_Static_assert(sizeof u == sizeof (int), "sizeof u != sizeof (int)");
_Static_assert(sizeof y == sizeof (int), "sizeof y != sizeof (int)");
int main(void)
{
return 0;
}