From: cuz Date: Sun, 24 Nov 2002 18:18:16 +0000 (+0000) Subject: Fixed a problem with the test expression in a for loop: It was not evaluated X-Git-Tag: V2.12.0~2018 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=89f00263af86905d08d8f0c61e105521cbe190dc;p=cc65 Fixed a problem with the test expression in a for loop: It was not evaluated correctly if it did not contain an explicit comparison operator. Removed an old hack from the test subroutine that did no longer work. git-svn-id: svn://svn.cc65.org/cc65/trunk@1619 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- diff --git a/src/cc65/expr.c b/src/cc65/expr.c index c9b00efef..692ba4d55 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -475,6 +475,23 @@ void ConstSubExpr (int (*F) (ExprDesc*), ExprDesc* Expr) +void CheckBoolExpr (ExprDesc* lval) +/* Check if the given expression is a boolean expression, output a diagnostic + * if not. + */ +{ + /* If it's an integer, it's ok. If it's not an integer, but a pointer, + * the pointer used in a boolean context is also ok + */ + if (!IsClassInt (lval->Type) && !IsClassPtr (lval->Type)) { + Error ("Boolean expression expected"); + /* To avoid any compiler errors, make the expression a valid int */ + MakeConstIntExpr (lval, 1); + } +} + + + /*****************************************************************************/ /* code */ /*****************************************************************************/ @@ -3108,70 +3125,63 @@ void intexpr (ExprDesc* lval) -void boolexpr (ExprDesc* lval) -/* Get a boolean expression */ -{ - /* Read an expression */ - expression (lval); - - /* If it's an integer, it's ok. If it's not an integer, but a pointer, - * the pointer used in a boolean context is also ok - */ - if (!IsClassInt (lval->Type) && !IsClassPtr (lval->Type)) { - Error ("Boolean expression expected"); - /* To avoid any compiler errors, make the expression a valid int */ - MakeConstIntExpr (lval, 1); - } -} - - - -void test (unsigned label, int cond) -/* Generate code to perform test and jump if false. */ +void Test (unsigned Label, int Invert) +/* Evaluate a boolean test expression and jump depending on the result of + * the test and on Invert. + */ { int k; ExprDesc lval; - /* Eat the parenthesis */ - ConsumeLParen (); - - /* Prepare the expression, setup labels */ + /* Evaluate the expression */ memset (&lval, 0, sizeof (lval)); - - /* Generate code to eval the expr */ k = expr (hie0, &lval); + + /* Check for a boolean expression */ + CheckBoolExpr (&lval); + + /* Check for a constant expression */ if (k == 0 && lval.Flags == E_MCONST) { + /* Constant rvalue */ - if (cond == 0 && lval.ConstVal == 0) { - g_jump (label); + if (!Invert && lval.ConstVal == 0) { + g_jump (Label); Warning ("Unreachable code"); - } else if (cond && lval.ConstVal) { - g_jump (label); + } else if (Invert && lval.ConstVal != 0) { + g_jump (Label); } - ConsumeRParen (); - return; - } - /* If the expr hasn't set condition codes, set the force-test flag */ - if ((lval.Test & E_CC) == 0) { - lval.Test |= E_FORCETEST; - } + } else { - /* Load the value into the primary register */ - exprhs (CF_FORCECHAR, k, &lval); + /* If the expr hasn't set condition codes, set the force-test flag */ + if ((lval.Test & E_CC) == 0) { + lval.Test |= E_FORCETEST; + } - /* Generate the jump */ - if (cond) { - g_truejump (CF_NONE, label); - } else { - /* Special case (putting this here is a small hack - but hey, the - * compiler itself is one big hack...): If a semicolon follows, we - * don't have a statement and may omit the jump. - */ - if (CurTok.Tok != TOK_SEMI) { - g_falsejump (CF_NONE, label); - } + /* Load the value into the primary register */ + exprhs (CF_FORCECHAR, k, &lval); + + /* Generate the jump */ + if (Invert) { + g_truejump (CF_NONE, Label); + } else { + g_falsejump (CF_NONE, Label); + } } +} + + + +void TestInParens (unsigned Label, int Invert) +/* Evaluate a boolean test expression in parenthesis and jump depending on + * the result of the test * and on Invert. + */ +{ + /* Eat the parenthesis */ + ConsumeLParen (); + + /* Do the test */ + Test (Label, Invert); /* Check for the closing brace */ ConsumeRParen (); @@ -3179,4 +3189,3 @@ void test (unsigned label, int cond) - diff --git a/src/cc65/expr.h b/src/cc65/expr.h index 77f1b7a60..7068be05c 100644 --- a/src/cc65/expr.h +++ b/src/cc65/expr.h @@ -37,6 +37,11 @@ void ConstSubExpr (int (*F) (ExprDesc*), ExprDesc* Expr); * from this input error. */ +void CheckBoolExpr (ExprDesc* lval); +/* Check if the given expression is a boolean expression, output a diagnostic + * if not. + */ + unsigned assignadjust (type* lhst, ExprDesc* rhs); /* Adjust the type of the right hand expression so that it can be assigned to * the type on the left hand side. This function is used for assignment and @@ -77,12 +82,6 @@ void ConstIntExpr (ExprDesc* Val); void intexpr (ExprDesc* lval); /* Get an integer expression */ -void boolexpr (ExprDesc* lval); -/* Get a boolean expression */ - -void test (unsigned label, int cond); -/* Generate code to perform test and jump if false. */ - int hie10 (ExprDesc* lval); /* Handle ++, --, !, unary - etc. */ @@ -95,6 +94,16 @@ int hie0 (ExprDesc* lval); void DefineData (ExprDesc* lval); /* Output a data definition for the given expression */ +void Test (unsigned Label, int Invert); +/* Evaluate a boolean test expression and jump depending on the result of + * the test and on Invert. + */ + +void TestInParens (unsigned Label, int Invert); +/* Evaluate a boolean test expression in parenthesis and jump depending on + * the result of the test * and on Invert. + */ + /* End of expr.h */ diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index ef29b6f02..ab091be3a 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -121,7 +121,7 @@ static int IfStatement (void) /* Generate a jump label and parse the condition */ Label1 = GetLocalLabel (); - test (Label1, 0); + TestInParens (Label1, 0); /* Parse the if body */ GotBreak = Statement (0); @@ -182,7 +182,7 @@ static void DoStatement (void) /* Parse the end condition */ Consume (TOK_WHILE, "`while' expected"); - test (loop, 1); + TestInParens (loop, 1); ConsumeSemi (); /* Define the break label */ @@ -213,7 +213,7 @@ static void WhileStatement (void) g_defcodelabel (loop); /* Test the loop condition */ - test (lab, 0); + TestInParens (lab, 0); /* Loop body */ Statement (&PendingToken); @@ -339,7 +339,6 @@ static void ForStatement (void) /* Handle a 'for' statement */ { ExprDesc lval1; - ExprDesc lval2; ExprDesc lval3; int HaveIncExpr; CodeMark IncExprStart; @@ -372,8 +371,7 @@ static void ForStatement (void) /* Parse the test expression */ if (CurTok.Tok != TOK_SEMI) { - boolexpr (&lval2); - g_truejump (CF_NONE, lstat); + Test (lstat, 1); g_jump (lab); } else { g_jump (lstat);