mirror of
https://github.com/cc65/cc65.git
synced 2025-02-04 13:32:54 +00:00
Disallowed arrays of incomplete types.
Fixed diagnostics on incomplete local arrays.
This commit is contained in:
parent
f5b1b69376
commit
1957dc7a5c
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user