diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 44b0d17e8..048819d50 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -3658,7 +3658,7 @@ static int hieAnd (ExprDesc* Expr, unsigned* TrueLab, int* TrueLabAllocated) */ DoDeferred (SQP_KEEP_NONE, Expr); - if (Expr->IVal == 0 && !ED_IsAddrExpr (Expr)) { + if (ED_IsConstFalse (Expr)) { /* Skip remaining */ Flags |= E_EVAL_UNEVAL; } @@ -3713,7 +3713,7 @@ static int hieAnd (ExprDesc* Expr, unsigned* TrueLab, int* TrueLabAllocated) */ DoDeferred (SQP_KEEP_NONE, &Expr2); - if (Expr2.IVal == 0 && !ED_IsAddrExpr (&Expr2)) { + if (ED_IsConstFalse (&Expr2)) { /* Skip remaining */ Flags |= E_EVAL_UNEVAL; /* The value of the expression will be false */ @@ -3826,7 +3826,7 @@ static void hieOr (ExprDesc *Expr) */ DoDeferred (SQP_KEEP_NONE, Expr); - if (Expr->IVal != 0 || ED_IsAddrExpr (Expr)) { + if (ED_IsConstTrue (Expr)) { /* Skip remaining */ Flags |= E_EVAL_UNEVAL; } @@ -3878,7 +3878,7 @@ static void hieOr (ExprDesc *Expr) */ DoDeferred (SQP_KEEP_NONE, &Expr2); - if (Expr2.IVal != 0 || ED_IsAddrExpr (&Expr2)) { + if (ED_IsConstTrue (&Expr2)) { /* Skip remaining */ Flags |= E_EVAL_UNEVAL; /* The result is always true */ @@ -3945,6 +3945,7 @@ static void hieQuest (ExprDesc* Expr) /* Check if it's a ternary expression */ if (CurTok.Tok == TOK_QUEST) { + /* The constant condition must be compile-time known as well */ int ConstantCond = ED_IsConstBool (Expr); unsigned Flags = Expr->Flags & E_MASK_KEEP_RESULT; @@ -3955,9 +3956,13 @@ static void hieQuest (ExprDesc* Expr) NextToken (); - /* Convert non-integer constant boolean */ - if (ED_IsAddrExpr (Expr)) { + /* Convert non-integer constant to boolean constant, so that we may just + ** check it in the same way. + */ + if (ED_IsConstTrue (Expr)) { ED_MakeConstBool (Expr, 1); + } else if (ED_IsConstFalse (Expr)) { + ED_MakeConstBool (Expr, 0); } if (!ConstantCond) { diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index aa98e1531..d1113d9a5 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -397,6 +397,30 @@ int ED_IsConstBool (const ExprDesc* Expr) +int ED_IsConstTrue (const ExprDesc* Expr) +/* Return true if the constant expression can be evaluated as boolean true at +** compile time. +*/ +{ + /* Non-zero arithmetics and objects addresses are boolean true */ + return (ED_IsConstAbsInt (Expr) && Expr->IVal != 0) || + (ED_IsAddrExpr (Expr)); +} + + + +int ED_IsConstFalse (const ExprDesc* Expr) +/* Return true if the constant expression can be evaluated as boolean false at +** compile time. +*/ +{ + /* Zero arithmetics and null pointers are boolean false */ + return (ED_IsConstAbsInt (Expr) && Expr->IVal == 0) || + ED_IsNullPtr (Expr); +} + + + int ED_IsConst (const ExprDesc* Expr) /* Return true if the expression denotes a constant of some sort. This can be a ** numeric constant, the address of a global variable (maybe with offset) or @@ -449,7 +473,7 @@ int ED_IsNullPtr (const ExprDesc* Expr) int ED_IsBool (const ExprDesc* Expr) -/* Return true of the expression can be treated as a boolean, that is, it can +/* Return true if the expression can be treated as a boolean, that is, it can ** be an operand to a compare operation. */ { diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index 844af1566..a4f5eb848 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -643,6 +643,16 @@ int ED_IsConstAbsInt (const ExprDesc* Expr); int ED_IsConstBool (const ExprDesc* Expr); /* Return true if the expression can be constantly evaluated as a boolean. */ +int ED_IsConstTrue (const ExprDesc* Expr); +/* Return true if the constant expression can be evaluated as boolean true at +** compile time. +*/ + +int ED_IsConstFalse (const ExprDesc* Expr); +/* Return true if the constant expression can be evaluated as boolean false at +** compile time. +*/ + int ED_IsConst (const ExprDesc* Expr); /* Return true if the expression denotes a constant of some sort. This can be a ** numeric constant, the address of a global variable (maybe with offset) or @@ -668,7 +678,7 @@ int ED_IsNullPtr (const ExprDesc* Expr); /* Return true if the given expression is a NULL pointer constant */ int ED_IsBool (const ExprDesc* Expr); -/* Return true of the expression can be treated as a boolean, that is, it can +/* Return true if the expression can be treated as a boolean, that is, it can ** be an operand to a compare operation with 0/NULL. */