From 8e0b2f083356f206b6f5529d0d60b32fff3a7a0a Mon Sep 17 00:00:00 2001 From: acqn Date: Thu, 20 Aug 2020 07:52:20 +0800 Subject: [PATCH] Object addresses as non-NULL in boolean context. --- src/cc65/expr.c | 32 +++++++++++++++++++++----------- src/cc65/exprdesc.c | 8 ++++++++ src/cc65/exprdesc.h | 3 +++ src/cc65/testexpr.c | 5 +++++ 4 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 7fb6e455f..94109d559 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1912,6 +1912,9 @@ void hie10 (ExprDesc* Expr) if (ED_IsConstAbs (Expr)) { /* Constant expression */ Expr->IVal = !Expr->IVal; + } else if (ED_IsAddrExpr (Expr)) { + /* Address != NULL, so !Address == 0 */ + ED_MakeConstBool (Expr, 0); } else { /* Not constant, load into the primary */ LoadExpr (CF_NONE, Expr); @@ -3222,7 +3225,7 @@ static int hieAnd (ExprDesc* Expr, unsigned* TrueLab, int* TrueLabAllocated) Error ("Scalar expression expected"); ED_MakeConstBool (Expr, 0); } else if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { - if (!ED_IsConstAbs (Expr)) { + if (!ED_IsConstBool (Expr)) { /* Set the test flag */ ED_RequireTest (Expr); @@ -3237,7 +3240,7 @@ static int hieAnd (ExprDesc* Expr, unsigned* TrueLab, int* TrueLabAllocated) /* Generate the jump */ g_falsejump (CF_NONE, FalseLab); - } else if (Expr->IVal == 0) { + } else if (Expr->IVal == 0 && !ED_IsAddrExpr (Expr)) { /* Skip remaining */ Flags |= E_EVAL_UNEVAL; } @@ -3264,7 +3267,7 @@ static int hieAnd (ExprDesc* Expr, unsigned* TrueLab, int* TrueLabAllocated) Error ("Scalar expression expected"); ED_MakeConstBool (&Expr2, 0); } else if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { - if (!ED_IsConstAbs (&Expr2)) { + if (!ED_IsConstBool (&Expr2)) { ED_RequireTest (&Expr2); LoadExpr (CF_FORCECHAR, &Expr2); @@ -3276,7 +3279,7 @@ static int hieAnd (ExprDesc* Expr, unsigned* TrueLab, int* TrueLabAllocated) /* We need the true label for the last expression */ HasTrueJump = 1; } - } else if (Expr2.IVal == 0) { + } else if (Expr2.IVal == 0 && !ED_IsAddrExpr (&Expr2)) { /* Skip remaining */ Flags |= E_EVAL_UNEVAL; /* The value of the expression will be false */ @@ -3313,7 +3316,8 @@ static int hieAnd (ExprDesc* Expr, unsigned* TrueLab, int* TrueLabAllocated) } /* Convert to bool */ - if (ED_IsConstAbs (Expr) && Expr->IVal != 0) { + if ((ED_IsConstAbs (Expr) && Expr->IVal != 0) || + ED_IsAddrExpr (Expr)) { ED_MakeConstBool (Expr, 1); } else { Expr->Type = type_bool; @@ -3354,7 +3358,7 @@ static void hieOr (ExprDesc *Expr) ED_MakeConstBool (Expr, 0); } else if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { - if (!ED_IsConstAbs (Expr)) { + if (!ED_IsConstBool (Expr)) { /* Test the lhs if we haven't had && operators. If we had them, the ** jump is already in place and there's no need to do the test. */ @@ -3377,7 +3381,7 @@ static void hieOr (ExprDesc *Expr) /* Jump to TrueLab if true */ g_truejump (CF_NONE, TrueLab); } - } else if (Expr->IVal != 0) { + } else if (Expr->IVal != 0 || ED_IsAddrExpr (Expr)) { /* Skip remaining */ Flags |= E_EVAL_UNEVAL; } @@ -3406,7 +3410,7 @@ static void hieOr (ExprDesc *Expr) ED_MakeConstBool (&Expr2, 0); } else if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) { - if (!ED_IsConstAbs (&Expr2)) { + if (!ED_IsConstBool (&Expr2)) { /* If there is more to come, add shortcut boolean eval */ if (!AndOp) { ED_RequireTest (&Expr2); @@ -3418,7 +3422,7 @@ static void hieOr (ExprDesc *Expr) } g_truejump (CF_NONE, TrueLab); } - } else if (Expr2.IVal != 0) { + } else if (Expr2.IVal != 0 || ED_IsAddrExpr (&Expr2)) { /* Skip remaining */ Flags |= E_EVAL_UNEVAL; /* The result is always true */ @@ -3429,7 +3433,8 @@ static void hieOr (ExprDesc *Expr) } /* Convert to bool */ - if (ED_IsConstAbs (Expr) && Expr->IVal != 0) { + if ((ED_IsConstAbs (Expr) && Expr->IVal != 0) || + ED_IsAddrExpr (Expr)) { ED_MakeConstBool (Expr, 1); } else { Expr->Type = type_bool; @@ -3483,7 +3488,7 @@ static void hieQuest (ExprDesc* Expr) /* Check if it's a ternary expression */ if (CurTok.Tok == TOK_QUEST) { - int ConstantCond = ED_IsConstAbsInt (Expr); + int ConstantCond = ED_IsConstBool (Expr); unsigned Flags = Expr->Flags & E_MASK_KEEP_RESULT; ED_Init (&Expr2); @@ -3493,6 +3498,11 @@ static void hieQuest (ExprDesc* Expr) NextToken (); + /* Convert non-integer constant boolean */ + if (ED_IsAddrExpr (Expr)) { + ED_MakeConstBool (Expr, 1); + } + if (!ConstantCond) { /* Condition codes not set, request a test */ ED_RequireTest (Expr); diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index 62738bed7..e82d0fafc 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -389,6 +389,14 @@ int ED_IsConstAbsInt (const ExprDesc* Expr) +int ED_IsConstBool (const ExprDesc* Expr) +/* Return true if the expression can be constantly evaluated as a boolean. */ +{ + return ED_IsConstAbsInt (Expr) || ED_IsAddrExpr (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 diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index c435b3c38..463828db6 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -640,6 +640,9 @@ int ED_IsConstAbs (const ExprDesc* Expr); int ED_IsConstAbsInt (const ExprDesc* Expr); /* Return true if the expression is a constant (numeric) integer. */ +int ED_IsConstBool (const ExprDesc* Expr); +/* Return true if the expression can be constantly evaluated as a boolean. */ + 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 diff --git a/src/cc65/testexpr.c b/src/cc65/testexpr.c index b924eaa40..80fe4bc3d 100644 --- a/src/cc65/testexpr.c +++ b/src/cc65/testexpr.c @@ -77,6 +77,11 @@ unsigned Test (unsigned Label, int Invert) g_jump (Label); } + } else if (ED_IsAddrExpr (&Expr)) { + + /* Object addresses are non-NULL */ + Result = 1; + } else { /* Result is unknown */