Fixed tracking and checking flexible array members.
This commit is contained in:
@@ -963,12 +963,19 @@ static SymEntry* ParseUnionDecl (const char* Name)
|
|||||||
AddBitField (Decl.Ident, Decl.Type, 0, 0, FieldWidth,
|
AddBitField (Decl.Ident, Decl.Type, 0, 0, FieldWidth,
|
||||||
SignednessSpecified);
|
SignednessSpecified);
|
||||||
} else {
|
} else {
|
||||||
|
Entry = AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, 0);
|
||||||
if (IsAnonName (Decl.Ident)) {
|
if (IsAnonName (Decl.Ident)) {
|
||||||
Entry = AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, 0);
|
|
||||||
Entry->V.A.ANumber = UnionTagEntry->V.S.ACount++;
|
Entry->V.A.ANumber = UnionTagEntry->V.S.ACount++;
|
||||||
AliasAnonStructFields (&Decl, Entry);
|
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");
|
Error ("Flexible array member cannot be first struct field");
|
||||||
}
|
}
|
||||||
FlexibleMember = 1;
|
FlexibleMember = 1;
|
||||||
|
Flags |= SC_HAVEFAM;
|
||||||
|
|
||||||
/* Assume zero for size calculations */
|
/* Assume zero for size calculations */
|
||||||
SetElementCount (Decl.Type, FLEXIBLE);
|
SetElementCount (Decl.Type, FLEXIBLE);
|
||||||
}
|
}
|
||||||
@@ -1156,13 +1165,21 @@ static SymEntry* ParseStructDecl (const char* Name)
|
|||||||
StructSize += BitOffs / CHAR_BITS;
|
StructSize += BitOffs / CHAR_BITS;
|
||||||
BitOffs %= CHAR_BITS;
|
BitOffs %= CHAR_BITS;
|
||||||
} else {
|
} else {
|
||||||
|
Entry = AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, StructSize);
|
||||||
if (IsAnonName (Decl.Ident)) {
|
if (IsAnonName (Decl.Ident)) {
|
||||||
Entry = AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, StructSize);
|
|
||||||
Entry->V.A.ANumber = StructTagEntry->V.S.ACount++;
|
Entry->V.A.ANumber = StructTagEntry->V.S.ACount++;
|
||||||
AliasAnonStructFields (&Decl, Entry);
|
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) {
|
if (!FlexibleMember) {
|
||||||
StructSize += SizeOf (Decl.Type);
|
StructSize += SizeOf (Decl.Type);
|
||||||
}
|
}
|
||||||
@@ -2361,11 +2378,17 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers)
|
|||||||
/* Number of elements determined by initializer */
|
/* Number of elements determined by initializer */
|
||||||
SetElementCount (T, Count);
|
SetElementCount (T, Count);
|
||||||
ElementCount = Count;
|
ElementCount = Count;
|
||||||
} else if (ElementCount == FLEXIBLE && AllowFlexibleMembers) {
|
} else if (ElementCount == FLEXIBLE) {
|
||||||
/* In non ANSI mode, allow initialization of flexible array
|
if (AllowFlexibleMembers) {
|
||||||
** members.
|
/* In non ANSI mode, allow initialization of flexible array
|
||||||
*/
|
** members.
|
||||||
ElementCount = Count;
|
*/
|
||||||
|
ElementCount = Count;
|
||||||
|
} else {
|
||||||
|
/* Forbid */
|
||||||
|
Error ("Initializing flexible array member is forbidden");
|
||||||
|
ElementCount = Count;
|
||||||
|
}
|
||||||
} else if (Count < ElementCount) {
|
} else if (Count < ElementCount) {
|
||||||
g_zerobytes ((ElementCount - Count) * ElementSize);
|
g_zerobytes ((ElementCount - Count) * ElementSize);
|
||||||
} else if (Count > ElementCount && HasCurly) {
|
} else if (Count > ElementCount && HasCurly) {
|
||||||
|
|||||||
@@ -107,6 +107,7 @@ struct CodeEntry;
|
|||||||
|
|
||||||
#define SC_ALIAS 0x01000000U /* Alias of anonymous field */
|
#define SC_ALIAS 0x01000000U /* Alias of anonymous field */
|
||||||
#define SC_FICTITIOUS 0x02000000U /* Symbol is fictitious */
|
#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);
|
int SymIsOutputFunc (const SymEntry* Sym);
|
||||||
/* Return true if this is a function that must be output */
|
/* 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)
|
#if defined(HAVE_INLINE)
|
||||||
INLINE const char* SymGetAsmName (const SymEntry* Sym)
|
INLINE const char* SymGetAsmName (const SymEntry* Sym)
|
||||||
/* Return the assembler label name for the symbol (beware: may be NULL!) */
|
/* Return the assembler label name for the symbol (beware: may be NULL!) */
|
||||||
|
|||||||
Reference in New Issue
Block a user