From 529b6c24ff2481b55123703cd25569ca8de717cc Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Fri, 17 Mar 2023 10:07:05 +0100 Subject: [PATCH] gas: apply md_register_arithmetic also to unary '+' Even a unary '+' has to be considered arithmetic; at least on x86 in Intel Syntax mode otherwise bogus insn operands may be accepted. Convert this specific case to binary + (i.e. 0 + ). (An implication is that md_operator(,1,) would need to deal with arch- specific equivalents of unary '+' is a similar way, if such an arch- specific variant would be specified in the first place.) To avoid duplicating what make_expr_symbol() does to construct a constant-zero expression, simply make its previously local variable a file-scope static one. This way there's also no need to invoke clean_up_expression(). --- gas/expr.c | 25 +++++++++++++++---------- gas/expr.h | 2 +- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/gas/expr.c b/gas/expr.c index ae24c281ba6..afb346ebab3 100644 --- a/gas/expr.c +++ b/gas/expr.c @@ -48,15 +48,16 @@ struct expr_symbol_line { }; static struct expr_symbol_line *expr_symbol_lines; + +static const expressionS zero = { .X_op = O_constant }; /* Build a dummy symbol to hold a complex expression. This is how we build expressions up out of other expressions. The symbol is put into the fake section expr_section. */ symbolS * -make_expr_symbol (expressionS *expressionP) +make_expr_symbol (const expressionS *expressionP) { - expressionS zero; symbolS *symbolP; struct expr_symbol_line *n; @@ -73,11 +74,6 @@ make_expr_symbol (expressionS *expressionP) as_bad (_("bignum invalid")); else as_bad (_("floating point number invalid")); - zero.X_op = O_constant; - zero.X_add_number = 0; - zero.X_unsigned = 0; - zero.X_extrabit = 0; - clean_up_expression (&zero); expressionP = &zero; } @@ -750,6 +746,10 @@ current_location (expressionS *expressionp) } } +#ifndef md_register_arithmetic +# define md_register_arithmetic 1 +#endif + /* In: Input_line_pointer points to 1st char of operand, which may be a space. @@ -1127,6 +1127,14 @@ operand (expressionS *expressionP, enum expr_mode mode) expressionP->X_op = O_logical_not; expressionP->X_add_number = 0; } + else if (!md_register_arithmetic && expressionP->X_op == O_register) + { + /* Convert to binary '+'. */ + expressionP->X_op_symbol = make_expr_symbol (expressionP); + expressionP->X_add_symbol = make_expr_symbol (&zero); + expressionP->X_add_number = 0; + expressionP->X_op = O_add; + } } else as_warn (_("Unary operator %c ignored because bad operand follows"), @@ -1890,9 +1898,6 @@ expr (int rankarg, /* Larger # is higher rank. */ ; } else -#endif -#ifndef md_register_arithmetic -# define md_register_arithmetic 1 #endif if (op_left == O_add && right.X_op == O_constant && (md_register_arithmetic || resultP->X_op != O_register)) diff --git a/gas/expr.h b/gas/expr.h index 8de272f2805..52574bd0115 100644 --- a/gas/expr.h +++ b/gas/expr.h @@ -182,7 +182,7 @@ extern void add_to_result (expressionS *, offsetT, int); extern void subtract_from_result (expressionS *, offsetT, int); extern segT expr (int, expressionS *, enum expr_mode); extern unsigned int get_single_number (void); -extern symbolS *make_expr_symbol (expressionS * expressionP); +extern symbolS *make_expr_symbol (const expressionS * expressionP); extern int expr_symbol_where (symbolS *, const char **, unsigned int *); extern void current_location (expressionS *); extern symbolS *expr_build_uconstant (offsetT); -- 2.30.2