[binutils-gdb] PR23800, .eqv doesn't always defer expression evaluation

Alan Modra amodra@sourceware.org
Sat Oct 20 09:26:00 GMT 2018


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=e4c2619ad1f31cf73d275b027e8c0cf9c6e9597a

commit e4c2619ad1f31cf73d275b027e8c0cf9c6e9597a
Author: Alan Modra <amodra@gmail.com>
Date:   Sat Oct 20 11:12:46 2018 +1030

    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.

Diff:
---
 gas/ChangeLog                   | 11 +++++++++++
 gas/config/tc-spu.c             | 17 ++++++++++++++++-
 gas/expr.c                      |  7 +++++++
 gas/testsuite/gas/all/eqv-dot.d | 12 ++++++++++++
 gas/testsuite/gas/all/eqv-dot.s |  8 ++++++++
 gas/testsuite/gas/all/gas.exp   |  1 +
 6 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/gas/ChangeLog b/gas/ChangeLog
index 0ae0206..71dd3b8 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -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.
diff --git a/gas/config/tc-spu.c b/gas/config/tc-spu.c
index 474805b..6998e2b 100644
--- a/gas/config/tc-spu.c
+++ b/gas/config/tc-spu.c
@@ -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,7 +847,14 @@ spu_cons (int nbytes)
 		       &exp, 0, reloc);
 	}
       else
-	emit_expr (&exp, nbytes);
+	{
+	  /* 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++ == ',');
 
diff --git a/gas/expr.c b/gas/expr.c
index 074e0b3..bacfa4e 100644
--- a/gas/expr.c
+++ b/gas/expr.c
@@ -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))
diff --git a/gas/testsuite/gas/all/eqv-dot.d b/gas/testsuite/gas/all/eqv-dot.d
new file mode 100644
index 0000000..1545303
--- /dev/null
+++ b/gas/testsuite/gas/all/eqv-dot.d
@@ -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
diff --git a/gas/testsuite/gas/all/eqv-dot.s b/gas/testsuite/gas/all/eqv-dot.s
new file mode 100644
index 0000000..cd8cb91
--- /dev/null
+++ b/gas/testsuite/gas/all/eqv-dot.s
@@ -0,0 +1,8 @@
+	.data
+x:	.long 0, 1, 2, . - x
+ y = . - x
+ z == . - x
+	.long y
+	.long z
+	.long y
+	.long z
diff --git a/gas/testsuite/gas/all/gas.exp b/gas/testsuite/gas/all/gas.exp
index c1237f9..74988a1 100644
--- a/gas/testsuite/gas/all/gas.exp
+++ b/gas/testsuite/gas/all/gas.exp
@@ -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"



More information about the Binutils-cvs mailing list