1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-07 07:29:33 +00:00

Disallowed arrays of incomplete types.

Fixed diagnostics on incomplete local arrays.
This commit is contained in:
acqn 2020-08-15 06:27:11 +08:00 committed by Oliver Schmidt
parent f5b1b69376
commit 1957dc7a5c
3 changed files with 72 additions and 34 deletions

View File

@ -140,19 +140,10 @@ static void Parse (void)
comma = 0;
while (1) {
Declaration Decl;
Declaration Decl;
/* Read the next declaration */
ParseDecl (&Spec, &Decl, DM_NEED_IDENT);
if (Decl.Ident[0] == '\0') {
NextToken ();
break;
}
if ((Decl.StorageClass & SC_FICTITIOUS) == SC_FICTITIOUS) {
/* Failed parsing */
goto SkipOneDecl;
}
/* Check if we must reserve storage for the variable. We do this,
**
@ -163,8 +154,9 @@ static void Parse (void)
**
** This means that "extern int i;" will not get storage allocated.
*/
if ((Decl.StorageClass & SC_FUNC) != SC_FUNC &&
(Decl.StorageClass & SC_TYPEMASK) != SC_TYPEDEF) {
if ((Decl.StorageClass & SC_FUNC) != SC_FUNC &&
(Decl.StorageClass & SC_TYPEMASK) != SC_TYPEDEF &&
(Decl.StorageClass & SC_FICTITIOUS) != SC_FICTITIOUS) {
if ((Spec.Flags & DS_DEF_STORAGE) != 0 ||
(Decl.StorageClass & (SC_EXTERN|SC_STATIC)) == SC_STATIC ||
((Decl.StorageClass & SC_EXTERN) != 0 &&
@ -296,7 +288,6 @@ static void Parse (void)
}
SkipOneDecl:
/* Check for end of declaration list */
if (CurTok.Tok == TOK_COMMA) {
NextToken ();
@ -452,10 +443,6 @@ void Compile (const char* FileName)
}
Sym = GetSymType (GetElementType (Entry->Type));
if (Size == 0 && Sym != 0 && SymIsDef (Sym)) {
/* Array of 0-size elements */
Warning ("Array '%s[]' has 0-sized elements", Entry->Name);
}
}
/* For non-ESU types, Size != 0 */

View File

@ -457,6 +457,37 @@ static unsigned ParseOneStorageClass (void)
static void CheckArrayElementType (Type* DataType)
/* Check if data type consists of arrays of incomplete element types */
{
Type* T = DataType;
while (T->C != T_END) {
if (IsTypeArray (T)) {
++T;
if (IsIncompleteESUType (T)) {
/* We cannot have an array of incomplete elements */
Error ("Array of incomplete element type '%s'", GetFullTypeName (T));
} else if (SizeOf (T) == 0) {
/* If the array is multi-dimensional, try to get the true
** element type.
*/
if (IsTypeArray (T)) {
continue;
}
/* We could support certain 0-size element types as an extension */
if (!IsTypeVoid (T) || IS_Get (&Standard) != STD_CC65) {
Error ("Array of 0-size element type '%s'", GetFullTypeName (T));
}
}
} else {
++T;
}
}
}
static void ParseStorageClass (DeclSpec* D, unsigned DefStorage)
/* Parse a storage class */
{
@ -956,16 +987,16 @@ NextMember: if (CurTok.Tok != TOK_COMMA) {
FieldTab = GetSymTab ();
LeaveStructLevel ();
/* Empty union is not supported now */
if (UnionSize == 0) {
Error ("Empty union type '%s' is not supported", Name);
}
/* Return a fictitious symbol if errors occurred during parsing */
if (PrevErrorCount != ErrorCount) {
Flags |= SC_FICTITIOUS;
}
/* Empty union is not supported now */
if (UnionSize == 0) {
Error ("Empty union type '%s' is not supported", Name);
}
/* Make a real entry from the forward decl and return it */
return AddStructSym (Name, SC_UNION | SC_DEF | Flags, UnionSize, FieldTab);
}
@ -1160,16 +1191,16 @@ NextMember: if (CurTok.Tok != TOK_COMMA) {
FieldTab = GetSymTab ();
LeaveStructLevel ();
/* Empty struct is not supported now */
if (StructSize == 0) {
Error ("Empty struct type '%s' is not supported", Name);
}
/* Return a fictitious symbol if errors occurred during parsing */
if (PrevErrorCount != ErrorCount) {
Flags |= SC_FICTITIOUS;
}
/* Empty struct is not supported now */
if (StructSize == 0) {
Error ("Empty struct type '%s' is not supported", Name);
}
/* Make a real entry from the forward decl and return it */
return AddStructSym (Name, SC_STRUCT | SC_DEF | Flags, StructSize, FieldTab);
}
@ -1922,6 +1953,9 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode)
/* Do several fixes on qualifiers */
FixQualifiers (D->Type);
/* Check if the data type consists of any arrays of forbidden types */
CheckArrayElementType (D->Type);
/* If we have a function, add a special storage class */
if (IsTypeFunc (D->Type)) {
D->StorageClass |= SC_FUNC;
@ -1993,10 +2027,15 @@ void ParseDecl (const DeclSpec* Spec, Declaration* D, declmode_t Mode)
Error ("Invalid size in declaration (0x%06X)", Size);
}
}
}
if (PrevErrorCount != ErrorCount) {
/* Don't give storage if the declaration is not parsed correctly */
D->StorageClass |= SC_DECL | SC_FICTITIOUS;
if (PrevErrorCount != ErrorCount) {
/* Make the declaration fictitious if is is not parsed correctly */
D->StorageClass |= SC_DECL | SC_FICTITIOUS;
if (Mode == DM_NEED_IDENT && D->Ident[0] == '\0') {
/* Use a fictitious name for the identifier if it is missing */
AnonName (D->Ident, "global");
}
}
}
@ -2242,7 +2281,7 @@ static unsigned ParseArrayInit (Type* T, int* Braces, int AllowFlexibleMembers)
/* Get the array data */
Type* ElementType = GetElementType (T);
unsigned ElementSize = CheckedSizeOf (ElementType);
unsigned ElementSize = SizeOf (ElementType);
long ElementCount = GetElementCount (T);
/* Special handling for a character array initialized by a literal */

View File

@ -172,7 +172,11 @@ static void ParseRegisterDecl (Declaration* Decl, int Reg)
/* Cannot allocate a variable of zero size */
if (Size == 0) {
Error ("Variable '%s' has unknown size", Decl->Ident);
if (IsTypeArray (Decl->Type)) {
Error ("Array '%s' has unknown size", Decl->Ident);
} else {
Error ("Variable '%s' has unknown size", Decl->Ident);
}
}
}
@ -357,7 +361,11 @@ static void ParseAutoDecl (Declaration* Decl)
/* Cannot allocate a variable of zero size */
if (Size == 0) {
Error ("Variable '%s' has unknown size", Decl->Ident);
if (IsTypeArray (Decl->Type)) {
Error ("Array '%s' has unknown size", Decl->Ident);
} else {
Error ("Variable '%s' has unknown size", Decl->Ident);
}
}
}
@ -411,7 +419,11 @@ static void ParseStaticDecl (Declaration* Decl)
/* Cannot allocate a variable of zero size */
if (Size == 0) {
Error ("Variable '%s' has unknown size", Decl->Ident);
if (IsTypeArray (Decl->Type)) {
Error ("Array '%s' has unknown size", Decl->Ident);
} else {
Error ("Variable '%s' has unknown size", Decl->Ident);
}
}
}