--- a/gas/symbols.c
+++ b/gas/symbols.c
@@ -1871,20 +1871,32 @@ snapshot_symbol (symbolS **symbolPP, val
 	}
 
       *symbolPP = symbolP;
+      *valueP = exp.X_add_number;
 
-      /* A bogus input file can result in resolve_expression()
-	 generating a local symbol, so we have to check again.  */
+      /* We may have picked up a local symbol above: Check again.  */
       if (symbolP->flags.local_symbol)
 	{
 	  struct local_symbol *locsym = (struct local_symbol *) symbolP;
 
-	  *valueP = locsym->value;
+	  if (locsym->section == expr_section
+	      || locsym->section == absolute_section
+	      || locsym->section == reg_section)
+	    {
+	      switch (exp.X_op)
+		{
+		case O_constant:
+		case O_register:
+		  *valueP += locsym->value;
+		  break;
+		default:
+		  break;
+		}
+	    }
 	  *segP = locsym->section;
 	  *fragPP = locsym->frag;
 	}
       else
 	{
-	  *valueP = exp.X_add_number;
 	  *segP = symbolP->bsym->section;
 	  *fragPP = symbolP->frag;
 	}
--- a/gas/testsuite/gas/elf/elf.exp
+++ b/gas/testsuite/gas/elf/elf.exp
@@ -361,6 +361,8 @@ if { [is_elf_format] } then {
 
     run_list_test "line2" -I${srcdir}/$subdir
 
+    run_list_test "equ-rept"
+
     run_dump_test "pr25917"
     run_dump_test "bss"
     # Some targets treat .bss similar to .lcomm.
--- /dev/null
+++ b/gas/testsuite/gas/elf/equ-rept.l
@@ -0,0 +1,3 @@
+# The line should appear exactly twice.
+>output<
+>output<
--- /dev/null
+++ b/gas/testsuite/gas/elf/equ-rept.s
@@ -0,0 +1,7 @@
+	.equiv n, (.L1+2) + null - .L2
+	.equiv null, 0
+.L1: .L2:
+
+	.rept n
+	.print ">output<"
+	.endr
