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

More reliable test for true/false with addresses for AND, OR and ternary operators.

Minor comment typo fix.
This commit is contained in:
acqn 2021-03-13 14:27:11 +08:00 committed by Oliver Schmidt
parent f8835d2867
commit 3c2e7ce41c
3 changed files with 47 additions and 8 deletions

View File

@ -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) {

View File

@ -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.
*/
{

View File

@ -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.
*/