From 8e45a4c960b2366a0c6d1d83539be3b029b1bcbe Mon Sep 17 00:00:00 2001 From: acqn Date: Fri, 27 Oct 2023 23:46:10 +0800 Subject: [PATCH] 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. --- src/cc65/declare.c | 7 +++---- test/err/bug2016-fam-member.c | 7 ++++++- test/err/bug2017-fam-element.c | 14 +++++++++----- test/val/fam.c | 31 +++++++++++++++++++++++++++++++ 4 files changed, 49 insertions(+), 10 deletions(-) create mode 100644 test/val/fam.c diff --git a/src/cc65/declare.c b/src/cc65/declare.c index cf9c13059..b09c2ea17 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -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"); } } diff --git a/test/err/bug2016-fam-member.c b/test/err/bug2016-fam-member.c index 02c9ec275..473aae702 100644 --- a/test/err/bug2016-fam-member.c +++ b/test/err/bug2016-fam-member.c @@ -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; }; diff --git a/test/err/bug2017-fam-element.c b/test/err/bug2017-fam-element.c index 195ca6597..c97ae42ec 100644 --- a/test/err/bug2017-fam-element.c +++ b/test/err/bug2017-fam-element.c @@ -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 */ diff --git a/test/val/fam.c b/test/val/fam.c new file mode 100644 index 000000000..df5df2876 --- /dev/null +++ b/test/val/fam.c @@ -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; +}