1
0
mirror of https://github.com/cc65/cc65.git synced 2024-09-27 19:55:09 +00:00

Fixed tracking and checking flexible array members.

This commit is contained in:
acqn 2020-08-15 06:27:11 +08:00 committed by Oliver Schmidt
parent f54e01781b
commit 632da3f4ee
2 changed files with 45 additions and 11 deletions

View File

@ -963,12 +963,19 @@ static SymEntry* ParseUnionDecl (const char* Name)
AddBitField (Decl.Ident, Decl.Type, 0, 0, FieldWidth,
SignednessSpecified);
} else {
Entry = AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, 0);
if (IsAnonName (Decl.Ident)) {
Entry = AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, 0);
Entry->V.A.ANumber = UnionTagEntry->V.S.ACount++;
AliasAnonStructFields (&Decl, Entry);
} else {
AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, 0);
}
/* Check if the field itself has a flexible array member */
if (IsClassStruct (Decl.Type)) {
SymEntry* Sym = GetSymType (Decl.Type);
if (Sym && SymHasFlexibleArrayMember (Sym)) {
Entry->Flags |= SC_HAVEFAM;
Flags |= SC_HAVEFAM;
}
}
}
@ -1107,6 +1114,8 @@ static SymEntry* ParseStructDecl (const char* Name)
Error ("Flexible array member cannot be first struct field");
}
FlexibleMember = 1;
Flags |= SC_HAVEFAM;
/* Assume zero for size calculations */
SetElementCount (Decl.Type, FLEXIBLE);
}
@ -1156,13 +1165,21 @@ static SymEntry* ParseStructDecl (const char* Name)
StructSize += BitOffs / CHAR_BITS;
BitOffs %= CHAR_BITS;
} else {
Entry = AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, StructSize);
if (IsAnonName (Decl.Ident)) {
Entry = AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, StructSize);
Entry->V.A.ANumber = StructTagEntry->V.S.ACount++;
AliasAnonStructFields (&Decl, Entry);
} else {
AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, StructSize);
}
/* Check if the field itself has a flexible array member */
if (IsClassStruct (Decl.Type)) {
SymEntry* Sym = GetSymType (Decl.Type);
if (Sym && SymHasFlexibleArrayMember (Sym)) {
Entry->Flags |= SC_HAVEFAM;
Flags |= SC_HAVEFAM;
}
}
if (!FlexibleMember) {
StructSize += SizeOf (Decl.Type);
}
@ -2361,11 +2378,17 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers)
/* Number of elements determined by initializer */
SetElementCount (T, Count);
ElementCount = Count;
} else if (ElementCount == FLEXIBLE && AllowFlexibleMembers) {
/* In non ANSI mode, allow initialization of flexible array
** members.
*/
ElementCount = Count;
} else if (ElementCount == FLEXIBLE) {
if (AllowFlexibleMembers) {
/* In non ANSI mode, allow initialization of flexible array
** members.
*/
ElementCount = Count;
} else {
/* Forbid */
Error ("Initializing flexible array member is forbidden");
ElementCount = Count;
}
} else if (Count < ElementCount) {
g_zerobytes ((ElementCount - Count) * ElementSize);
} else if (Count > ElementCount && HasCurly) {

View File

@ -107,6 +107,7 @@ struct CodeEntry;
#define SC_ALIAS 0x01000000U /* Alias of anonymous field */
#define SC_FICTITIOUS 0x02000000U /* Symbol is fictitious */
#define SC_HAVEFAM 0x04000000U /* Type has a Flexible Array Member */
@ -272,6 +273,16 @@ INLINE int SymIsRegVar (const SymEntry* Sym)
int SymIsOutputFunc (const SymEntry* Sym);
/* Return true if this is a function that must be output */
#if defined(HAVE_INLINE)
INLINE int SymHasFlexibleArrayMember (const SymEntry* Sym)
/* Return true if the given entry has a flexible array member */
{
return ((Sym->Flags & SC_HAVEFAM) == SC_HAVEFAM);
}
#else
# define SymHasFlexibleArrayMember(Sym) (((Sym)->Flags & SC_HAVEFAM) == SC_HAVEFAM)
#endif
#if defined(HAVE_INLINE)
INLINE const char* SymGetAsmName (const SymEntry* Sym)
/* Return the assembler label name for the symbol (beware: may be NULL!) */