From: Jan Beulich Date: Fri, 10 Jan 2025 07:42:00 +0000 (+0100) Subject: gas: make deferred expression evaluation generally latch dot X-Git-Tag: binutils-2_44~212 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=044dd6345f7b275db1ed3b2b9bea7a3e46b1ea09;p=thirdparty%2Fbinutils-gdb.git gas: make deferred expression evaluation generally latch dot Deferring expression evaluation is often necessary. However, the value current_location() records typically is intended to represent the location at the point of use of the expression, with the exception being .eqv (or its == equivalent). Change how expr_defer behaves in this regard, and introduce a special mode just for pseudo_set() to use. Introduce a predicate to cover both "deferred" modes, and use it everywhere except in current_location(), where only the new mode wants checking for. --- diff --git a/gas/config/tc-m32r.c b/gas/config/tc-m32r.c index aa0acea7743..3505b3a13f7 100644 --- a/gas/config/tc-m32r.c +++ b/gas/config/tc-m32r.c @@ -2333,13 +2333,13 @@ m32r_parse_name (char const *name, /* If we have an absolute symbol or a reg, then we know its value now. */ segment = S_GET_SEGMENT (exprP->X_add_symbol); - if (mode != expr_defer && segment == absolute_section) + if (!expr_defer_p (mode) && segment == absolute_section) { exprP->X_op = O_constant; exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol); exprP->X_add_symbol = NULL; } - else if (mode != expr_defer && segment == reg_section) + else if (!expr_defer_p (mode) && segment == reg_section) { exprP->X_op = O_register; exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol); diff --git a/gas/config/tc-metag.c b/gas/config/tc-metag.c index bf084f7df13..f4364356d8f 100644 --- a/gas/config/tc-metag.c +++ b/gas/config/tc-metag.c @@ -6908,13 +6908,13 @@ metag_parse_name (char const * name, expressionS * exprP, enum expr_mode mode, /* If we have an absolute symbol or a reg, then we know its value now. */ segment = S_GET_SEGMENT (exprP->X_add_symbol); - if (mode != expr_defer && segment == absolute_section) + if (!expr_defer_p (mode) && segment == absolute_section) { exprP->X_op = O_constant; exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol); exprP->X_add_symbol = NULL; } - else if (mode != expr_defer && segment == reg_section) + else if (!expr_defer_p (mode) && segment == reg_section) { exprP->X_op = O_register; exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol); diff --git a/gas/config/tc-mn10300.c b/gas/config/tc-mn10300.c index 08f6a1c6aef..3fc7cac823a 100644 --- a/gas/config/tc-mn10300.c +++ b/gas/config/tc-mn10300.c @@ -2475,13 +2475,13 @@ mn10300_parse_name (char const *name, /* If we have an absolute symbol or a reg, then we know its value now. */ segment = S_GET_SEGMENT (exprP->X_add_symbol); - if (mode != expr_defer && segment == absolute_section) + if (!expr_defer_p (mode) && segment == absolute_section) { exprP->X_op = O_constant; exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol); exprP->X_add_symbol = NULL; } - else if (mode != expr_defer && segment == reg_section) + else if (!expr_defer_p (mode) && segment == reg_section) { exprP->X_op = O_register; exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol); diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c index 1ff1175d02a..d1de57e882c 100644 --- a/gas/config/tc-ppc.c +++ b/gas/config/tc-ppc.c @@ -902,7 +902,7 @@ ppc_parse_name (const char *name, expressionS *exp, enum expr_mode mode) /* If we have an absolute symbol or a reg, then we know its value now. Copy the symbol value expression to propagate X_md. */ bool done = false; - if (mode != expr_defer + if (!expr_defer_p (mode) && !S_FORCE_RELOC (sym, 0)) { segT segment = S_GET_SEGMENT (sym); diff --git a/gas/config/tc-sh.c b/gas/config/tc-sh.c index fe720e7eae9..d1a7c2516ec 100644 --- a/gas/config/tc-sh.c +++ b/gas/config/tc-sh.c @@ -3933,13 +3933,13 @@ sh_parse_name (char const *name, /* If we have an absolute symbol or a reg, then we know its value now. */ segment = S_GET_SEGMENT (exprP->X_add_symbol); - if (mode != expr_defer && segment == absolute_section) + if (!expr_defer_p (mode) && segment == absolute_section) { exprP->X_op = O_constant; exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol); exprP->X_add_symbol = NULL; } - else if (mode != expr_defer && segment == reg_section) + else if (!expr_defer_p (mode) && segment == reg_section) { exprP->X_op = O_register; exprP->X_add_number = S_GET_VALUE (exprP->X_add_symbol); diff --git a/gas/expr.c b/gas/expr.c index 5e59b7c5fa1..ccd89253ac1 100644 --- a/gas/expr.c +++ b/gas/expr.c @@ -738,7 +738,7 @@ current_location (expressionS *expressionp, enum expr_mode mode) else { expressionp->X_op = O_symbol; - if (mode != expr_defer) + if (mode != expr_defer_incl_dot) { expressionp->X_add_symbol = symbol_temp_new_now (); #ifdef tc_new_dot_label @@ -1387,14 +1387,14 @@ operand (expressionS *expressionP, enum expr_mode mode) /* If we have an absolute symbol or a reg, then we know its value now. */ segment = S_GET_SEGMENT (symbolP); - if (mode != expr_defer + if (!expr_defer_p (mode) && segment == absolute_section && !S_FORCE_RELOC (symbolP, 0)) { expressionP->X_op = O_constant; expressionP->X_add_number = S_GET_VALUE (symbolP); } - else if (mode != expr_defer && segment == reg_section) + else if (!expr_defer_p (mode) && segment == reg_section) { expressionP->X_op = O_register; expressionP->X_add_number = S_GET_VALUE (symbolP); @@ -1438,7 +1438,7 @@ operand (expressionS *expressionP, enum expr_mode mode) if (expressionP->X_add_symbol) symbol_mark_used (expressionP->X_add_symbol); - if (mode != expr_defer) + if (!expr_defer_p (mode)) { expressionP->X_add_symbol = symbol_clone_if_forward_ref (expressionP->X_add_symbol); @@ -1933,7 +1933,7 @@ expr (int rankarg, /* Larger # is higher rank. */ is_unsigned = resultP->X_unsigned && right.X_unsigned; - if (mode == expr_defer + if (expr_defer_p (mode) && ((resultP->X_add_symbol != NULL && S_IS_FORWARD_REF (resultP->X_add_symbol)) || (right.X_add_symbol != NULL diff --git a/gas/expr.h b/gas/expr.h index 351e6306740..14787c41343 100644 --- a/gas/expr.h +++ b/gas/expr.h @@ -153,9 +153,12 @@ enum expr_mode { expr_evaluate, expr_normal, - expr_defer + expr_defer, + expr_defer_incl_dot, }; +#define expr_defer_p(m) ((m) >= expr_defer) + /* "result" should be type (expressionS *). */ #define expression(result) expr (0, result, expr_normal) #define expression_and_evaluate(result) expr (0, result, expr_evaluate) diff --git a/gas/read.c b/gas/read.c index 5df1f3da588..c51536f44f9 100644 --- a/gas/read.c +++ b/gas/read.c @@ -4069,7 +4069,7 @@ pseudo_set (symbolS *symbolP) if (!S_IS_FORWARD_REF (symbolP)) (void) expression (&exp); else - (void) deferred_expression (&exp); + (void) expr (0, &exp, expr_defer_incl_dot); if (exp.X_op == O_illegal) as_bad (_("illegal expression"));