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

Merge pull request #2201 from acqn/Diagnostics

[cc65] Improved diagnostics
This commit is contained in:
Bob Andrews 2023-10-05 03:19:31 +02:00 committed by GitHub
commit bdb13350e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 49 additions and 12 deletions

View File

@ -178,7 +178,7 @@ static void Parse (void)
** or semicolon, it must be followed by a function body.
*/
if ((Decl.StorageClass & SC_FUNC) != 0) {
if (CurTok.Tok != TOK_COMMA && CurTok.Tok != TOK_SEMI) {
if (CurTok.Tok == TOK_LCURLY) {
/* A definition */
Decl.StorageClass |= SC_DEF;
@ -190,6 +190,10 @@ static void Parse (void)
FuncDef->Flags = (FuncDef->Flags & ~FD_EMPTY) | FD_VOID_PARAM;
}
} else {
if (CurTok.Tok != TOK_COMMA && CurTok.Tok != TOK_SEMI) {
Error ("Expected ',' or ';' after top level declarator");
}
/* Just a declaration */
Decl.StorageClass |= SC_DECL;
}
@ -325,7 +329,7 @@ static void Parse (void)
if (CurTok.Tok == TOK_SEMI) {
/* Prototype only */
NextToken ();
} else {
} else if (CurTok.Tok == TOK_LCURLY) {
/* Parse the function body */
NewFunc (Sym, FuncDef);

View File

@ -1452,7 +1452,7 @@ static void ParseTypeSpec (DeclSpec* D, typespec_t TSFlags, int* SignednessSpeci
NextToken ();
} else {
if (CurTok.Tok != TOK_LCURLY) {
Error ("Identifier expected");
Error ("Identifier expected for enum tag name");
}
AnonName (Ident, "enum");
}
@ -1504,8 +1504,8 @@ static void ParseTypeSpec (DeclSpec* D, typespec_t TSFlags, int* SignednessSpeci
/* FALL THROUGH */
default:
if ((TSFlags & TS_MASK_DEFAULT_TYPE) != TS_DEFAULT_TYPE_INT) {
Error ("Type expected");
if ((TSFlags & TS_MASK_DEFAULT_TYPE) == TS_DEFAULT_TYPE_NONE) {
D->Flags |= DS_NO_TYPE;
D->Type[0].C = T_INT;
D->Type[1].C = T_END;
} else {
@ -1553,8 +1553,7 @@ static const Type* ParamTypeCvt (Type* T)
static void ParseOldStyleParamList (FuncDesc* F)
/* Parse an old-style (K&R) parameter list */
{
/* Some fix point tokens that are used for error recovery */
static const token_t TokenList[] = { TOK_COMMA, TOK_RPAREN, TOK_SEMI };
unsigned PrevErrorCount = ErrorCount;
/* Parse params */
while (CurTok.Tok != TOK_RPAREN) {
@ -1572,8 +1571,11 @@ static void ParseOldStyleParamList (FuncDesc* F)
NextToken ();
} else {
/* Some fix point tokens that are used for error recovery */
static const token_t TokenList[] = { TOK_COMMA, TOK_RPAREN, TOK_SEMI };
/* Not a parameter name */
Error ("Identifier expected");
Error ("Identifier expected for parameter name");
/* Try some smart error recovery */
SkipTokens (TokenList, sizeof(TokenList) / sizeof(TokenList[0]));
@ -1608,6 +1610,12 @@ static void ParseOldStyleParamList (FuncDesc* F)
Error ("Illegal storage class");
}
/* Type must be specified */
if ((Spec.Flags & DS_NO_TYPE) != 0) {
Error ("Expected declaration specifiers");
break;
}
/* Parse a comma separated variable list */
while (1) {
@ -1655,6 +1663,14 @@ static void ParseOldStyleParamList (FuncDesc* F)
/* Variable list must be semicolon terminated */
ConsumeSemi ();
}
if (PrevErrorCount != ErrorCount) {
/* Some fix point tokens that are used for error recovery */
static const token_t TokenList[] = { TOK_COMMA, TOK_SEMI };
/* Try some smart error recovery */
SkipTokens (TokenList, sizeof(TokenList) / sizeof(TokenList[0]));
}
}
@ -1689,6 +1705,11 @@ static void ParseAnsiParamList (FuncDesc* F)
Spec.StorageClass = SC_AUTO | SC_PARAM | SC_DEF;
}
/* Type must be specified */
if ((Spec.Flags & DS_NO_TYPE) != 0) {
Error ("Type specifier missing");
}
/* Warn about new local type declaration */
if ((Spec.Flags & DS_NEW_TYPE_DECL) != 0) {
Warning ("'%s' will be invisible out of this function",
@ -1870,12 +1891,21 @@ static void DirectDecl (const DeclSpec* Spec, Declarator* D, declmode_t Mode)
} else {
if (Mode == DM_NEED_IDENT) {
/* Some fix point tokens that are used for error recovery */
static const token_t TokenList[] = { TOK_COMMA, TOK_SEMI };
static const token_t TokenList[] = { TOK_COMMA, TOK_SEMI, TOK_LCURLY, TOK_RCURLY };
Error ("Identifier expected");
/* Try some smart error recovery */
SkipTokens (TokenList, sizeof(TokenList) / sizeof(TokenList[0]));
/* Skip curly braces */
if (CurTok.Tok == TOK_LCURLY) {
static const token_t CurlyToken[] = { TOK_RCURLY };
SkipTokens (CurlyToken, sizeof(CurlyToken) / sizeof(CurlyToken[0]));
NextToken ();
} else if (CurTok.Tok == TOK_RCURLY) {
NextToken ();
}
}
D->Ident[0] = '\0';
}

View File

@ -71,8 +71,9 @@ enum typespec_t {
/* Masks for the Flags field in DeclSpec */
#define DS_DEF_STORAGE 0x0001U /* Default storage class used */
#define DS_DEF_TYPE 0x0002U /* Default type used */
#define DS_EXTRA_TYPE 0x0004U /* Extra type declared */
#define DS_NO_TYPE 0x0002U /* No type explicitly specified */
#define DS_DEF_TYPE 0x0006U /* Default type used */
#define DS_EXTRA_TYPE 0x0008U /* Extra type declared */
#define DS_NEW_TYPE_DECL 0x0010U /* New type declared */
#define DS_NEW_TYPE_DEF 0x0020U /* New type defined */
#define DS_NEW_TYPE (DS_NEW_TYPE_DECL | DS_NEW_TYPE_DEF)

View File

@ -1439,7 +1439,7 @@ static void StructRef (ExprDesc* Expr)
/* Skip the token and check for an identifier */
NextToken ();
if (CurTok.Tok != TOK_IDENT) {
Error ("Identifier expected");
Error ("Identifier expected for %s member", GetBasicTypeName (Expr->Type));
/* Make the expression an integer at address zero */
ED_MakeConstAbs (Expr, 0, type_int);
return;

View File

@ -1,3 +1,5 @@
bug1889-missing-identifier.c:3: Error: Identifier expected
bug1889-missing-identifier.c:3: Error: ';' expected
bug1889-missing-identifier.c:3: Warning: Implicit 'int' is an obsolete feature
bug1889-missing-identifier.c:4: Error: Identifier expected
bug1889-missing-identifier.c:4: Warning: Implicit 'int' is an obsolete feature