Fixed empty declarations in structs/unions.

This commit is contained in:
acqn 2023-11-15 18:17:36 +08:00
parent 0eb38770bd
commit 5332eeecc2
2 changed files with 76 additions and 54 deletions

View File

@ -983,33 +983,36 @@ static SymEntry* ParseUnionSpec (const char* Name, unsigned* DSFlags)
/* Check for a bit-field declaration */
FieldWidth = ParseFieldWidth (&Decl);
/* Ignore zero sized bit fields in a union */
if (FieldWidth == 0) {
goto NextMember;
}
/* Check for fields without a name */
/* Check for fields without names */
if (Decl.Ident[0] == '\0') {
/* In cc65 mode, we allow anonymous structs/unions within
** a union.
*/
if (IS_Get (&Standard) >= STD_CC65 && IsClassStruct (Decl.Type)) {
/* This is an anonymous struct or union */
AnonFieldName (Decl.Ident, GetBasicTypeName (Decl.Type), UnionTagEntry->V.S.ACount);
if (FieldWidth < 0) {
/* In cc65 mode, we allow anonymous structs/unions within
** a union.
*/
SymEntry* TagEntry;
if (IS_Get (&Standard) >= STD_CC65 &&
IsClassStruct (Decl.Type) &&
(TagEntry = GetESUTagSym (Decl.Type)) &&
SymHasAnonName (TagEntry)) {
/* This is an anonymous struct or union */
AnonFieldName (Decl.Ident, GetBasicTypeName (Decl.Type), UnionTagEntry->V.S.ACount);
/* Ignore CVR qualifiers */
if (IsQualConst (Decl.Type) || IsQualVolatile (Decl.Type) || IsQualRestrict (Decl.Type)) {
Warning ("Anonymous %s qualifiers are ignored", GetBasicTypeName (Decl.Type));
Decl.Type[0].C &= ~T_QUAL_CVR;
/* Ignore CVR qualifiers */
if (IsQualConst (Decl.Type) || IsQualVolatile (Decl.Type) || IsQualRestrict (Decl.Type)) {
Warning ("Anonymous %s qualifiers are ignored", GetBasicTypeName (Decl.Type));
Decl.Type[0].C &= ~T_QUAL_CVR;
}
} else {
/* A non bit-field without a name is legal but useless */
Warning ("Declaration does not declare anything");
goto NextMember;
}
} else {
/* A non bit-field without a name is legal but useless */
Warning ("Declaration does not declare anything");
} else if (FieldWidth > 0) {
/* A bit-field without a name will get an anonymous one */
AnonName (Decl.Ident, "bit-field");
}
}
/* Check for incomplete types including 'void' */
if (IsIncompleteType (Decl.Type)) {
} else if (IsIncompleteType (Decl.Type)) {
Error ("Field '%s' has incomplete type '%s'",
Decl.Ident,
GetFullTypeName (Decl.Type));
@ -1020,6 +1023,11 @@ static SymEntry* ParseUnionSpec (const char* Name, unsigned* DSFlags)
Flags |= SC_HAVECONST;
}
/* Ignore zero sized bit fields in a union */
if (FieldWidth == 0) {
goto NextMember;
}
/* Handle sizes */
FieldSize = SizeOf (Decl.Type);
if (FieldSize > UnionSize) {
@ -1180,36 +1188,17 @@ static SymEntry* ParseStructSpec (const char* Name, unsigned* DSFlags)
}
}
/* Apart from the above, a bit field with width 0 is not processed
** further.
*/
if (FieldWidth == 0) {
goto NextMember;
}
/* Check if this field is a flexible array member, and
** calculate the size of the field.
*/
if (IsTypeArray (Decl.Type) && GetElementCount (Decl.Type) == UNSPECIFIED) {
/* Array with unspecified size */
if (StructSize == 0) {
Error ("Flexible array member cannot be first struct field");
}
FlexibleMember = 1;
Flags |= SC_HAVEFAM;
/* Assume zero for size calculations */
SetElementCount (Decl.Type, FLEXIBLE);
}
/* Check for fields without names */
if (Decl.Ident[0] == '\0') {
if (FieldWidth < 0) {
/* In cc65 mode, we allow anonymous structs/unions within
** a struct.
*/
if (IS_Get (&Standard) >= STD_CC65 && IsClassStruct (Decl.Type)) {
SymEntry* TagEntry;
if (IS_Get (&Standard) >= STD_CC65 &&
IsClassStruct (Decl.Type) &&
(TagEntry = GetESUTagSym (Decl.Type)) &&
SymHasAnonName (TagEntry)) {
/* This is an anonymous struct or union */
AnonFieldName (Decl.Ident, GetBasicTypeName (Decl.Type), StructTagEntry->V.S.ACount);
@ -1221,18 +1210,34 @@ static SymEntry* ParseStructSpec (const char* Name, unsigned* DSFlags)
} else {
/* A non bit-field without a name is legal but useless */
Warning ("Declaration does not declare anything");
goto NextMember;
}
} else {
} else if (FieldWidth > 0) {
/* A bit-field without a name will get an anonymous one */
AnonName (Decl.Ident, "bit-field");
}
}
} else {
/* Check if this field is a flexible array member, and
** calculate the size of the field.
*/
if (IsTypeArray (Decl.Type) && GetElementCount (Decl.Type) == UNSPECIFIED) {
/* Array with unspecified size */
if (StructSize == 0) {
Error ("Flexible array member cannot be first struct field");
}
FlexibleMember = 1;
Flags |= SC_HAVEFAM;
/* Check for incomplete types including 'void' */
if (IsIncompleteType (Decl.Type)) {
Error ("Field '%s' has incomplete type '%s'",
Decl.Ident,
GetFullTypeName (Decl.Type));
/* Assume zero for size calculations */
SetElementCount (Decl.Type, FLEXIBLE);
}
if (IsIncompleteType (Decl.Type)) {
Error ("Field '%s' has incomplete type '%s'",
Decl.Ident,
GetFullTypeName (Decl.Type));
}
}
/* Check for const types */
@ -1240,6 +1245,13 @@ static SymEntry* ParseStructSpec (const char* Name, unsigned* DSFlags)
Flags |= SC_HAVECONST;
}
/* Apart from the above, a bit field with width 0 is not processed
** further.
*/
if (FieldWidth == 0) {
goto NextMember;
}
/* Add a field entry to the table */
if (FieldWidth > 0) {
/* Full bytes have already been added to the StructSize,

View File

@ -5,6 +5,11 @@
unsigned failures;
struct X {
const int; /* Useless empty declaration */
const void; /* Useless empty declaration */
const struct U; /* Useless(?) declaration */
const struct V { int a; }; /* Useless(?) declaration */
const struct { /* Qualifier ignored in cc65 */
int a;
};
@ -14,6 +19,11 @@ struct X {
};
union Y {
const int; /* Useless empty declaration */
const void; /* Useless empty declaration */
const union W; /* Useless(?) declaration */
const union T { int a; }; /* Useless(?) declaration */
const struct { /* Qualifier ignored in cc65 */
int a;
};