mirror of
https://github.com/cc65/cc65.git
synced 2025-01-26 17:36:57 +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:
parent
f8835d2867
commit
3c2e7ce41c
@ -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) {
|
||||
|
@ -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.
|
||||
*/
|
||||
{
|
||||
|
@ -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.
|
||||
*/
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user