From 1957dc7a5c36bab15fd2021ce52b5b7e4f2f7479 Mon Sep 17 00:00:00 2001 From: acqn Date: Sat, 15 Aug 2020 06:27:11 +0800 Subject: [PATCH] Disallowed arrays of incomplete types. Fixed diagnostics on incomplete local arrays. --- src/cc65/compile.c | 21 +++------------ src/cc65/declare.c | 67 ++++++++++++++++++++++++++++++++++++---------- src/cc65/locals.c | 18 ++++++++++--- 3 files changed, 72 insertions(+), 34 deletions(-) diff --git a/src/cc65/compile.c b/src/cc65/compile.c index 82dc7ec63..3296968f6 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -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 */ diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 6c1dbd751..0bfbcedd2 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -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 */ diff --git a/src/cc65/locals.c b/src/cc65/locals.c index a21a09e8e..4323943a1 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -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); + } } }