Fixed tracking and checking flexible array members.
This commit is contained in:
parent
f54e01781b
commit
632da3f4ee
2 changed files with 45 additions and 11 deletions
|
@ -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) {
|
||||
|
|
|
@ -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!) */
|
||||
|
|
Loading…
Add table
Reference in a new issue