PR23800, .eqv doesn't always defer expression evaluation

.eqv (and ==) ought not simplify expressions involving dot or other
symbols set by .eqv.  If such simplification occurs, the value of dot
will be that at the assignment rather than at the place where the
symbol is used.

	PR 23800
	* expr.c (expr): Don't simplify expressions involving forward_ref
	symbols when mode is expr_defer.
	* config/tc-spu.c (spu_cons): Parse expression using normal
	expression evaluation if @ppu is not detected.
	* testsuite/gas/all/eqv-dot.d,
	* testsuite/gas/all/eqv-dot.s: New test.
	* testsuite/gas/all/gas.exp: Run it.
This commit is contained in:
Alan Modra 2018-10-20 11:12:46 +10:30
parent ac85e67c05
commit e4c2619ad1
6 changed files with 55 additions and 1 deletions

View File

@ -1,3 +1,14 @@
2018-10-20 Alan Modra <amodra@gmail.com>
PR 23800
* expr.c (expr): Don't simplify expressions involving forward_ref
symbols when mode is expr_defer.
* config/tc-spu.c (spu_cons): Parse expression using normal
expression evaluation if @ppu is not detected.
* testsuite/gas/all/eqv-dot.d,
* testsuite/gas/all/eqv-dot.s: New test.
* testsuite/gas/all/gas.exp: Run it.
2018-10-19 Tamar Christina <tamar.christina@arm.com>
* testsuite/gas/arm/undefined-insn-arm.d: Widen pe skip.

View File

@ -815,6 +815,11 @@ spu_cons (int nbytes)
do
{
char *save = input_line_pointer;
/* Use deferred_expression here so that an expression involving
a symbol that happens to be defined already as an spu symbol,
is not resolved. */
deferred_expression (&exp);
if ((exp.X_op == O_symbol
|| exp.X_op == O_constant)
@ -829,9 +834,12 @@ spu_cons (int nbytes)
{
expressionS new_exp;
save = input_line_pointer;
expression (&new_exp);
if (new_exp.X_op == O_constant)
exp.X_add_number += new_exp.X_add_number;
else
input_line_pointer = save;
}
reloc = nbytes == 4 ? BFD_RELOC_SPU_PPU32 : BFD_RELOC_SPU_PPU64;
@ -839,8 +847,15 @@ spu_cons (int nbytes)
&exp, 0, reloc);
}
else
{
/* Don't use deferred_expression for anything else.
deferred_expression won't evaulate dot at the point it is
used. */
input_line_pointer = save;
expression (&exp);
emit_expr (&exp, nbytes);
}
}
while (*input_line_pointer++ == ',');
/* Put terminator back into stream. */

View File

@ -1838,6 +1838,13 @@ expr (int rankarg, /* Larger # is higher rank. */
right.X_op_symbol = NULL;
}
if (mode == expr_defer
&& ((resultP->X_add_symbol != NULL
&& S_IS_FORWARD_REF (resultP->X_add_symbol))
|| (right.X_add_symbol != NULL
&& S_IS_FORWARD_REF (right.X_add_symbol))))
goto general;
/* Optimize common cases. */
#ifdef md_optimize_expr
if (md_optimize_expr (resultP, op_left, &right))

View File

@ -0,0 +1,12 @@
#objdump: -s -j .data
#name: eqv involving dot
# bfin doesn't support 'symbol = expression'
# tic4x has 4 octets per byte
#notarget: bfin-*-* tic4x-*-*
.*: .*
Contents of section \.data:
0000 (0+00 0+01 0+02 0+0c|000+ 010+ 020+ 0c0+) .*
0010 (0+10 0+14 0+10 0+1c|100+ 140+ 100+ 1c0+) .*
#pass

View File

@ -0,0 +1,8 @@
.data
x: .long 0, 1, 2, . - x
y = . - x
z == . - x
.long y
.long z
.long y
.long z

View File

@ -91,6 +91,7 @@ case $target_triplet in {
gas_test "eqv-ok.s" "" "" ".eqv support"
gas_test_error "eqv-bad.s" "" ".eqv for symbol already set"
run_dump_test eqv-dot
if { ![istarget "bfin-*-*"] } then {
gas_test "assign-ok.s" "" "" "== assignment support"