From 251e984ba88ca9afe62a2b22d789a453d2e6f2cf Mon Sep 17 00:00:00 2001 From: acqn Date: Fri, 5 Aug 2022 14:03:51 +0800 Subject: [PATCH] Fixed error recovery with preprocessing directives failures. --- src/cc65/ppexpr.c | 40 +++++++++++++++++++++++++++++++++------- src/cc65/ppexpr.h | 2 +- src/cc65/preproc.c | 2 +- src/cc65/scanner.c | 4 +++- src/cc65/scanner.h | 1 + 5 files changed, 39 insertions(+), 10 deletions(-) diff --git a/src/cc65/ppexpr.c b/src/cc65/ppexpr.c index da25e12f1..af2c1de3b 100644 --- a/src/cc65/ppexpr.c +++ b/src/cc65/ppexpr.c @@ -90,12 +90,14 @@ static void PPExprInit (PPExpr* Expr) static void PPErrorSkipLine (void) -/* Skip the remain tokens till the end of the line and set the expression -** parser error flag. +/* Set the expression parser error flag, skip the remain tokens till the end +** of the line, clear the current and the next tokens. */ { - SkipTokens (0, 0); PPEvaluationFailed = 1; + SkipTokens (0, 0); + CurTok.Tok = TOK_CEOF; + NextTok.Tok = TOK_CEOF; } @@ -148,6 +150,10 @@ static void PPhiePrimary (PPExpr* Expr) Expr->IVal = 0; break; + case TOK_CEOF: + /* Error recovery */ + break; + default: /* Illegal expression in PP mode */ PPError ("Preprocessor expression expected"); @@ -252,6 +258,10 @@ void PPhie10 (PPExpr* Expr) Expr->IVal = !Expr->IVal; break; + case TOK_CEOF: + /* Error recovery */ + break; + case TOK_STAR: case TOK_AND: case TOK_SIZEOF: @@ -286,7 +296,7 @@ static void PPhie_internal (const token_t* Ops, /* List of generators */ /* Get the right hand side */ hienext (&Rhs); - if (PPEvaluationEnabled) { + if (PPEvaluationEnabled && !PPEvaluationFailed) { /* If either side is unsigned, the result is unsigned */ Expr->Flags |= Rhs.Flags & PPEXPR_UNSIGNED; @@ -407,7 +417,7 @@ static void PPhie_compare (const token_t* Ops, /* List of generators */ /* Get the right hand side */ hienext (&Rhs); - if (PPEvaluationEnabled) { + if (PPEvaluationEnabled && !PPEvaluationFailed) { /* If either side is unsigned, the comparison is unsigned */ Expr->Flags |= Rhs.Flags & PPEXPR_UNSIGNED; @@ -501,7 +511,7 @@ static void PPhie7 (PPExpr* Expr) PPhie8 (&Rhs); /* Evaluate */ - if (PPEvaluationEnabled) { + if (PPEvaluationEnabled && !PPEvaluationFailed) { /* To shift by a negative value is equivalent to shift to the ** opposite direction. */ @@ -761,46 +771,57 @@ static void PPhie1 (PPExpr* Expr) case TOK_ASSIGN: PPError ("Token \"=\" is not valid in preprocessor expressions"); + PPErrorSkipLine (); break; case TOK_PLUS_ASSIGN: PPError ("Token \"+=\" is not valid in preprocessor expressions"); + PPErrorSkipLine (); break; case TOK_MINUS_ASSIGN: PPError ("Token \"-=\" is not valid in preprocessor expressions"); + PPErrorSkipLine (); break; case TOK_MUL_ASSIGN: PPError ("Token \"*=\" is not valid in preprocessor expressions"); + PPErrorSkipLine (); break; case TOK_DIV_ASSIGN: PPError ("Token \"/=\" is not valid in preprocessor expressions"); + PPErrorSkipLine (); break; case TOK_MOD_ASSIGN: PPError ("Token \"%%=\" is not valid in preprocessor expressions"); + PPErrorSkipLine (); break; case TOK_SHL_ASSIGN: PPError ("Token \"<<=\" is not valid in preprocessor expressions"); + PPErrorSkipLine (); break; case TOK_SHR_ASSIGN: PPError ("Token \">>=\" is not valid in preprocessor expressions"); + PPErrorSkipLine (); break; case TOK_AND_ASSIGN: PPError ("Token \"&=\" is not valid in preprocessor expressions"); + PPErrorSkipLine (); break; case TOK_OR_ASSIGN: PPError ("Token \"|=\" is not valid in preprocessor expressions"); + PPErrorSkipLine (); break; case TOK_XOR_ASSIGN: PPError ("Token \"^=\" is not valid in preprocessor expressions"); + PPErrorSkipLine (); break; default: @@ -827,12 +848,13 @@ static void PPhie0 (PPExpr* Expr) -void ParsePPExpr (PPExpr* Expr) +void ParsePPExprInLine (PPExpr* Expr) /* Parse a line for PP expression */ { /* Initialize the parser status */ PPEvaluationFailed = 0; PPEvaluationEnabled = 1; + NextLineDisabled = 1; /* Parse */ PPExprInit (Expr); @@ -841,5 +863,9 @@ void ParsePPExpr (PPExpr* Expr) /* If the evaluation fails, the result is always zero */ if (PPEvaluationFailed) { Expr->IVal = 0; + PPEvaluationFailed = 0; } + + /* Restore parser status */ + NextLineDisabled = 0; } diff --git a/src/cc65/ppexpr.h b/src/cc65/ppexpr.h index 683c6c49d..5e9968a2b 100644 --- a/src/cc65/ppexpr.h +++ b/src/cc65/ppexpr.h @@ -66,7 +66,7 @@ struct PPExpr -void ParsePPExpr (PPExpr* Expr); +void ParsePPExprInLine (PPExpr* Expr); /* Parse a line for PP expression */ diff --git a/src/cc65/preproc.c b/src/cc65/preproc.c index c06545e77..4cbef33f3 100644 --- a/src/cc65/preproc.c +++ b/src/cc65/preproc.c @@ -1279,7 +1279,7 @@ static int DoIf (int Skip) NextToken (); /* Call the expression parser */ - ParsePPExpr (&Expr); + ParsePPExprInLine (&Expr); /* Restore input source */ MLine = InitLine (MLine); diff --git a/src/cc65/scanner.c b/src/cc65/scanner.c index 98e9e1c06..c7e9bb6c2 100644 --- a/src/cc65/scanner.c +++ b/src/cc65/scanner.c @@ -69,6 +69,7 @@ Token CurTok; /* The current token */ Token NextTok; /* The next token */ +int NextLineDisabled; /* Disabled to read next line */ @@ -188,7 +189,8 @@ static int SkipWhite (void) { while (1) { while (CurC == '\0') { - if (PreprocessNextLine () == 0) { + /* If reading next line fails or is forbidden, bail out */ + if (NextLineDisabled || PreprocessNextLine () == 0) { return 0; } } diff --git a/src/cc65/scanner.h b/src/cc65/scanner.h index e6a362bf3..cd34cbbe8 100644 --- a/src/cc65/scanner.h +++ b/src/cc65/scanner.h @@ -210,6 +210,7 @@ struct Token { extern Token CurTok; /* The current token */ extern Token NextTok; /* The next token */ +extern int NextLineDisabled; /* Disabled to read next line */