diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 543cca421..3367b04d7 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -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,6 +1571,9 @@ 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 for parameter name"); @@ -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", diff --git a/src/cc65/declare.h b/src/cc65/declare.h index ee9e1fc63..0facccba3 100644 --- a/src/cc65/declare.h +++ b/src/cc65/declare.h @@ -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)