--- a/gas/expr.c
+++ b/gas/expr.c
@@ -728,7 +728,7 @@ mri_char_constant (expressionS *expressi
    handles the magic symbol `.'.  */
 
 void
-current_location (expressionS *expressionp)
+current_location (expressionS *expressionp, enum expr_mode mode)
 {
   if (now_seg == absolute_section)
     {
@@ -738,7 +738,15 @@ current_location (expressionS *expressio
   else
     {
       expressionp->X_op = O_symbol;
-      expressionp->X_add_symbol = &dot_symbol;
+      if (mode != expr_defer)
+	{
+	  expressionp->X_add_symbol = symbol_temp_new_now ();
+#ifdef tc_new_dot_label
+	  tc_new_dot_label (expressionp->X_add_symbol);
+#endif
+	}
+      else
+	  expressionp->X_add_symbol = &dot_symbol;
       expressionp->X_add_number = 0;
     }
 }
@@ -1215,14 +1223,14 @@ operand (expressionS *expressionP, enum
       if (is_part_of_name (*input_line_pointer))
 	goto isname;
 
-      current_location (expressionP);
+      current_location (expressionP, mode);
       break;
 #endif
 
     case '.':
       if (!is_part_of_name (*input_line_pointer))
 	{
-	  current_location (expressionP);
+	  current_location (expressionP, mode);
 	  break;
 	}
       else if ((strncasecmp (input_line_pointer, "startof.", 8) == 0
@@ -1309,7 +1317,7 @@ operand (expressionS *expressionP, enum
       if (! flag_m68k_mri || is_part_of_name (*input_line_pointer))
 	goto de_fault;
 
-      current_location (expressionP);
+      current_location (expressionP, mode);
       break;
 #endif
 
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -168,7 +168,7 @@ static int i386_finalize_displacement (s
 static int i386_att_operand (char *);
 static int i386_intel_operand (char *, int);
 static int i386_intel_simplify (expressionS *);
-static int i386_intel_parse_name (const char *, expressionS *);
+static int i386_intel_parse_name (const char *, expressionS *, enum expr_mode);
 static const reg_entry *parse_register (const char *, char **);
 static const char *parse_insn (const char *, char *, enum parse_mode);
 static char *parse_operands (char *, const char *);
@@ -16644,7 +16644,10 @@ parse_register (const char *reg_string,
 }
 
 int
-i386_parse_name (char *name, expressionS *e, char *nextcharP)
+i386_parse_name (char *name,
+		 expressionS *e,
+		 enum expr_mode mode,
+		 char *nextcharP)
 {
   const reg_entry *r = NULL;
   char *end = input_line_pointer;
@@ -16669,7 +16672,7 @@ i386_parse_name (char *name, expressionS
     }
   input_line_pointer = end;
   *end = 0;
-  return intel_syntax ? i386_intel_parse_name (name, e) : 0;
+  return intel_syntax ? i386_intel_parse_name (name, e, mode) : 0;
 }
 
 void
--- a/gas/config/tc-i386.h
+++ b/gas/config/tc-i386.h
@@ -191,8 +191,8 @@ extern bool i386_check_label (void);
 extern int i386_unrecognized_line (int);
 #define tc_unrecognized_line i386_unrecognized_line
 
-extern int i386_parse_name (char *, expressionS *, char *);
-#define md_parse_name(s, e, m, c) i386_parse_name (s, e, c)
+extern int i386_parse_name (char *, expressionS *, enum expr_mode, char *);
+#define md_parse_name(s, e, m, c) i386_parse_name (s, e, m, c)
 
 extern operatorT i386_operator (const char *name, unsigned int operands, char *);
 #define md_operator i386_operator
--- a/gas/config/tc-i386-intel.c
+++ b/gas/config/tc-i386-intel.c
@@ -236,13 +236,15 @@ operatorT i386_operator (const char *nam
   return O_absent;
 }
 
-static int i386_intel_parse_name (const char *name, expressionS *e)
+static int i386_intel_parse_name (const char *name,
+				  expressionS *e,
+				  enum expr_mode mode)
 {
   unsigned int j;
 
   if (! strcmp (name, "$"))
     {
-      current_location (e);
+      current_location (e, mode);
       return 1;
     }
 
--- a/gas/config/tc-mmix.h
+++ b/gas/config/tc-mmix.h
@@ -62,7 +62,7 @@ extern int mmix_gnu_syntax;
  (! mmix_gnu_syntax						\
   && (name[0] == '@'						\
       ? (! is_part_of_name (name[1])				\
-	 && (current_location (exp), 1))			\
+	 && (current_location (exp, mode), 1))			\
       : ((name[0] == ':' || ISUPPER (name[0]))			\
 	 && mmix_parse_predefined_name (name, exp))))
 
--- a/gas/expr.h
+++ b/gas/expr.h
@@ -184,7 +184,7 @@ extern segT expr (int, expressionS *, en
 extern unsigned int get_single_number (void);
 extern symbolS *make_expr_symbol (const expressionS * expressionP);
 extern int expr_symbol_where (symbolS *, const char **, unsigned int *);
-extern void current_location (expressionS *);
+extern void current_location (expressionS *, enum expr_mode);
 extern symbolS *expr_build_uconstant (offsetT);
 extern symbolS *expr_build_dot (void);
 extern uint32_t generic_bignum_to_int32 (void);
