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,17 +983,17 @@ static SymEntry* ParseUnionSpec (const char* Name, unsigned* DSFlags)
/* Check for a bit-field declaration */ /* Check for a bit-field declaration */
FieldWidth = ParseFieldWidth (&Decl); FieldWidth = ParseFieldWidth (&Decl);
/* Ignore zero sized bit fields in a union */ /* Check for fields without names */
if (FieldWidth == 0) {
goto NextMember;
}
/* Check for fields without a name */
if (Decl.Ident[0] == '\0') { if (Decl.Ident[0] == '\0') {
if (FieldWidth < 0) {
/* In cc65 mode, we allow anonymous structs/unions within /* In cc65 mode, we allow anonymous structs/unions within
** a union. ** a union.
*/ */
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 */ /* This is an anonymous struct or union */
AnonFieldName (Decl.Ident, GetBasicTypeName (Decl.Type), UnionTagEntry->V.S.ACount); AnonFieldName (Decl.Ident, GetBasicTypeName (Decl.Type), UnionTagEntry->V.S.ACount);
@@ -1005,11 +1005,14 @@ static SymEntry* ParseUnionSpec (const char* Name, unsigned* DSFlags)
} else { } else {
/* A non bit-field without a name is legal but useless */ /* A non bit-field without a name is legal but useless */
Warning ("Declaration does not declare anything"); Warning ("Declaration does not declare anything");
}
}
/* Check for incomplete types including 'void' */ goto NextMember;
if (IsIncompleteType (Decl.Type)) { }
} else if (FieldWidth > 0) {
/* A bit-field without a name will get an anonymous one */
AnonName (Decl.Ident, "bit-field");
}
} else if (IsIncompleteType (Decl.Type)) {
Error ("Field '%s' has incomplete type '%s'", Error ("Field '%s' has incomplete type '%s'",
Decl.Ident, Decl.Ident,
GetFullTypeName (Decl.Type)); GetFullTypeName (Decl.Type));
@@ -1020,6 +1023,11 @@ static SymEntry* ParseUnionSpec (const char* Name, unsigned* DSFlags)
Flags |= SC_HAVECONST; Flags |= SC_HAVECONST;
} }
/* Ignore zero sized bit fields in a union */
if (FieldWidth == 0) {
goto NextMember;
}
/* Handle sizes */ /* Handle sizes */
FieldSize = SizeOf (Decl.Type); FieldSize = SizeOf (Decl.Type);
if (FieldSize > UnionSize) { if (FieldSize > UnionSize) {
@@ -1180,13 +1188,36 @@ static SymEntry* ParseStructSpec (const char* Name, unsigned* DSFlags)
} }
} }
/* Apart from the above, a bit field with width 0 is not processed /* Check for fields without names */
** further. if (Decl.Ident[0] == '\0') {
if (FieldWidth < 0) {
/* In cc65 mode, we allow anonymous structs/unions within
** a struct.
*/ */
if (FieldWidth == 0) { 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);
/* 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; goto NextMember;
} }
} 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 /* Check if this field is a flexible array member, and
** calculate the size of the field. ** calculate the size of the field.
*/ */
@@ -1202,44 +1233,25 @@ static SymEntry* ParseStructSpec (const char* Name, unsigned* DSFlags)
SetElementCount (Decl.Type, FLEXIBLE); 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)) {
/* This is an anonymous struct or union */
AnonFieldName (Decl.Ident, GetBasicTypeName (Decl.Type), StructTagEntry->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;
}
} else {
/* A non bit-field without a name is legal but useless */
Warning ("Declaration does not declare anything");
}
} else {
/* 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)) { if (IsIncompleteType (Decl.Type)) {
Error ("Field '%s' has incomplete type '%s'", Error ("Field '%s' has incomplete type '%s'",
Decl.Ident, Decl.Ident,
GetFullTypeName (Decl.Type)); GetFullTypeName (Decl.Type));
} }
}
/* Check for const types */ /* Check for const types */
if (IsQualConst (Decl.Type)) { if (IsQualConst (Decl.Type)) {
Flags |= SC_HAVECONST; 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 */ /* Add a field entry to the table */
if (FieldWidth > 0) { if (FieldWidth > 0) {
/* Full bytes have already been added to the StructSize, /* Full bytes have already been added to the StructSize,

View File

@@ -5,6 +5,11 @@
unsigned failures; unsigned failures;
struct X { 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 */ const struct { /* Qualifier ignored in cc65 */
int a; int a;
}; };
@@ -14,6 +19,11 @@ struct X {
}; };
union Y { 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 */ const struct { /* Qualifier ignored in cc65 */
int a; int a;
}; };