Made certain types of comparison between addresses in constant expressions work.

This commit is contained in:
acqn
2021-02-15 09:50:46 +08:00
committed by Oliver Schmidt
parent 99c7fe0ada
commit 8eeaaa3f36

View File

@@ -2361,7 +2361,6 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
void (*hienext) (ExprDesc*)) void (*hienext) (ExprDesc*))
/* Helper function for the compare operators */ /* Helper function for the compare operators */
{ {
CodeMark Mark0;
CodeMark Mark1; CodeMark Mark1;
CodeMark Mark2; CodeMark Mark2;
const GenDesc* Gen; const GenDesc* Gen;
@@ -2370,7 +2369,6 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
int rconst; /* Operand is a constant */ int rconst; /* Operand is a constant */
GetCodePos (&Mark0);
ExprWithCheck (hienext, Expr); ExprWithCheck (hienext, Expr);
while ((Gen = FindGen (CurTok.Tok, Ops)) != 0) { while ((Gen = FindGen (CurTok.Tok, Ops)) != 0) {
@@ -2395,11 +2393,11 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
GetCodePos (&Mark1); GetCodePos (&Mark1);
ltype = TypeOf (Expr->Type); ltype = TypeOf (Expr->Type);
if (ED_IsConstAbs (Expr)) { if (ED_IsConstAbs (Expr)) {
/* Constant value */ /* Numeric constant value */
GetCodePos (&Mark2); GetCodePos (&Mark2);
g_push (ltype | CF_CONST, Expr->IVal); g_push (ltype | CF_CONST, Expr->IVal);
} else { } else {
/* Value not constant */ /* Value not numeric constant */
LoadExpr (CF_NONE, Expr); LoadExpr (CF_NONE, Expr);
GetCodePos (&Mark2); GetCodePos (&Mark2);
g_push (ltype, 0); g_push (ltype, 0);
@@ -2413,10 +2411,10 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
Expr2.Type = PointerTo (Expr2.Type); Expr2.Type = PointerTo (Expr2.Type);
} }
/* Check for a constant expression */ /* Check for a numeric constant expression */
rconst = (ED_IsConstAbs (&Expr2) && ED_CodeRangeIsEmpty (&Expr2)); rconst = (ED_IsConstAbs (&Expr2) && ED_CodeRangeIsEmpty (&Expr2));
if (!rconst) { if (!rconst) {
/* Not constant, load into the primary */ /* Not numeric constant, load into the primary */
LoadExpr (CF_NONE, &Expr2); LoadExpr (CF_NONE, &Expr2);
} }
@@ -2475,10 +2473,76 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
} }
} }
/* Check for const operands */ /* Check for numeric constant operands */
if (ED_IsConstAbs (Expr) && rconst) { if ((ED_IsAddrExpr (Expr) && ED_IsNullPtr (&Expr2)) ||
(ED_IsNullPtr (Expr) && ED_IsAddrExpr (&Expr2))) {
/* Both operands are constant, remove the generated code */ /* Object addresses are inequal to null pointer */
Expr->IVal = (Tok != TOK_EQ);
if (ED_IsNullPtr (&Expr2)) {
if (Tok == TOK_LT || Tok == TOK_LE) {
Expr->IVal = 0;
}
} else {
if (Tok == TOK_GT || Tok == TOK_GE) {
Expr->IVal = 0;
}
}
/* Get rid of unwanted flags */
ED_MakeConstBool (Expr, Expr->IVal);
/* The result is constant, this is suspicious when not in
** preprocessor mode.
*/
WarnConstCompareResult (Expr);
if (ED_CodeRangeIsEmpty (&Expr2)) {
/* Both operands are static, remove the load code */
RemoveCode (&Mark1);
} else {
/* Drop pushed lhs */
g_drop (sizeofarg (ltype));
pop (ltype);
}
} else if (ED_IsAddrExpr (Expr) &&
ED_IsAddrExpr (&Expr2) &&
Expr->Sym == Expr2.Sym) {
/* Evaluate the result for static addresses */
unsigned long Val1 = Expr->IVal;
unsigned long Val2 = Expr2.IVal;
switch (Tok) {
case TOK_EQ: Expr->IVal = (Val1 == Val2); break;
case TOK_NE: Expr->IVal = (Val1 != Val2); break;
case TOK_LT: Expr->IVal = (Val1 < Val2); break;
case TOK_LE: Expr->IVal = (Val1 <= Val2); break;
case TOK_GE: Expr->IVal = (Val1 >= Val2); break;
case TOK_GT: Expr->IVal = (Val1 > Val2); break;
default: Internal ("hie_compare: got token 0x%X\n", Tok);
}
/* Get rid of unwanted flags */
ED_MakeConstBool (Expr, Expr->IVal);
/* If the result is constant, this is suspicious when not in
** preprocessor mode.
*/
WarnConstCompareResult (Expr);
if (ED_CodeRangeIsEmpty (&Expr2)) {
/* Both operands are static, remove the load code */
RemoveCode (&Mark1);
} else {
/* Drop pushed lhs */
g_drop (sizeofarg (ltype));
pop (ltype);
}
} else if (ED_IsConstAbs (Expr) && rconst) {
/* Both operands are numeric constant, remove the generated code */
RemoveCode (&Mark1); RemoveCode (&Mark1);
/* Determine if this is a signed or unsigned compare */ /* Determine if this is a signed or unsigned compare */
@@ -2522,33 +2586,6 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
*/ */
WarnConstCompareResult (Expr); WarnConstCompareResult (Expr);
} else if (ED_CodeRangeIsEmpty (&Expr2) &&
((ED_IsAddrExpr (Expr) && ED_IsNullPtr (&Expr2)) ||
(ED_IsNullPtr (Expr) && (ED_IsAddrExpr (&Expr2))))) {
/* Object addresses are inequal to null pointer */
Expr->IVal = (Tok != TOK_EQ);
if (ED_IsNullPtr (&Expr2)) {
if (Tok == TOK_LT || Tok == TOK_LE) {
Expr->IVal = 0;
}
} else {
if (Tok == TOK_GT || Tok == TOK_GE) {
Expr->IVal = 0;
}
}
/* Get rid of unwanted flags */
ED_MakeConstBool (Expr, Expr->IVal);
/* If the result is constant, this is suspicious when not in
** preprocessor mode.
*/
WarnConstCompareResult (Expr);
/* Both operands are static, remove the generated code */
RemoveCode (&Mark1);
} else { } else {
/* Determine the signedness of the operands */ /* Determine the signedness of the operands */