This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix pr4079


Even though this one is a bug fix, I'm not inclined to commit it to
2.18, just in case I wrongly reject perfectly good assembly.

	PR gas/4079
	* config/tc-i386.c (x86_cons): Complain about invalid @got etc.
	expressions.
	(i386_immediate): Detect and complain about more cases of
	invalid immediate expressions.  Return failure rather than
	converting them to zero.
	(i386_displacement): Likewise.

Index: gas/config/tc-i386.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-i386.c,v
retrieving revision 1.272
diff -u -p -r1.272 tc-i386.c
--- gas/config/tc-i386.c	9 Aug 2007 13:50:51 -0000	1.272
+++ gas/config/tc-i386.c	17 Aug 2007 02:28:12 -0000
@@ -4575,6 +4575,17 @@ x86_cons (expressionS *exp, int size)
 				+ (input_line_pointer - gotfree_input_line)
 				+ adjust);
 	  free (gotfree_input_line);
+	  if (exp->X_op == O_constant
+	      || exp->X_op == O_absent
+	      || exp->X_op == O_illegal
+	      || exp->X_op == O_register
+	      || exp->X_op == O_big)
+	    {
+	      char c = *input_line_pointer;
+	      *input_line_pointer = 0;
+	      as_bad (_("missing or invalid expression `%s'"), save);
+	      *input_line_pointer = c;
+	    }
 	}
     }
   else
@@ -4651,15 +4662,16 @@ i386_immediate (char *imm_start)
   if (gotfree_input_line)
     free (gotfree_input_line);
 
-  if (exp->X_op == O_absent || exp->X_op == O_big)
+  if (exp->X_op == O_absent
+      || exp->X_op == O_illegal
+      || exp->X_op == O_big
+      || (gotfree_input_line
+	  && (exp->X_op == O_constant
+	      || exp->X_op == O_register)))
     {
-      /* Missing or bad expr becomes absolute 0.  */
-      as_bad (_("missing or invalid immediate expression `%s' taken as 0"),
+      as_bad (_("missing or invalid immediate expression `%s'"),
 	      imm_start);
-      exp->X_op = O_constant;
-      exp->X_add_number = 0;
-      exp->X_add_symbol = (symbolS *) 0;
-      exp->X_op_symbol = (symbolS *) 0;
+      return 0;
     }
   else if (exp->X_op == O_constant)
     {
@@ -4758,6 +4770,7 @@ i386_displacement (char *disp_start, cha
   char *gotfree_input_line;
   int bigdisp, override;
   unsigned int types = Disp;
+  int ret;
 
   if (i.disp_operands == MAX_MEMORY_OPERANDS)
     {
@@ -4866,10 +4879,10 @@ i386_displacement (char *disp_start, cha
 #if GCC_ASM_O_HACK
   RESTORE_END_STRING (disp_end + 1);
 #endif
-  RESTORE_END_STRING (disp_end);
   input_line_pointer = save_input_line_pointer;
   if (gotfree_input_line)
     free (gotfree_input_line);
+  ret = 1;
 
   /* We do this to make sure that the section symbol is in
      the symbol table.  We will ultimately change the relocation
@@ -4879,13 +4892,7 @@ i386_displacement (char *disp_start, cha
       || i.reloc[this_operand] == BFD_RELOC_X86_64_GOTOFF64)
     {
       if (exp->X_op != O_symbol)
-	{
-	  as_bad (_("bad expression used with @%s"),
-		  (i.reloc[this_operand] == BFD_RELOC_X86_64_GOTPCREL
-		   ? "GOTPCREL"
-		   : "GOTOFF"));
-	  return 0;
-	}
+	goto inv_disp;
 
       if (S_IS_LOCAL (exp->X_add_symbol)
 	  && S_GET_SEGMENT (exp->X_add_symbol) != undefined_section)
@@ -4900,36 +4907,40 @@ i386_displacement (char *disp_start, cha
 	i.reloc[this_operand] = BFD_RELOC_32;
     }
 
-  if (exp->X_op == O_absent || exp->X_op == O_big)
+  else if (exp->X_op == O_absent
+	   || exp->X_op == O_illegal
+	   || exp->X_op == O_big
+	   || (gotfree_input_line
+	       && (exp->X_op == O_constant
+		   || exp->X_op == O_register)))
     {
-      /* Missing or bad expr becomes absolute 0.  */
-      as_bad (_("missing or invalid displacement expression `%s' taken as 0"),
+    inv_disp:
+      as_bad (_("missing or invalid displacement expression `%s'"),
 	      disp_start);
-      exp->X_op = O_constant;
-      exp->X_add_number = 0;
-      exp->X_add_symbol = (symbolS *) 0;
-      exp->X_op_symbol = (symbolS *) 0;
+      ret = 0;
     }
 
 #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
-  if (exp->X_op != O_constant
-      && OUTPUT_FLAVOR == bfd_target_aout_flavour
-      && exp_seg != absolute_section
-      && exp_seg != text_section
-      && exp_seg != data_section
-      && exp_seg != bss_section
-      && exp_seg != undefined_section
-      && !bfd_is_com_section (exp_seg))
+  else if (exp->X_op != O_constant
+	   && OUTPUT_FLAVOR == bfd_target_aout_flavour
+	   && exp_seg != absolute_section
+	   && exp_seg != text_section
+	   && exp_seg != data_section
+	   && exp_seg != bss_section
+	   && exp_seg != undefined_section
+	   && !bfd_is_com_section (exp_seg))
     {
       as_bad (_("unimplemented segment %s in operand"), exp_seg->name);
-      return 0;
+      ret = 0;
     }
 #endif
 
+  RESTORE_END_STRING (disp_end);
+
   if (!(i.types[this_operand] & ~Disp))
     i.types[this_operand] &= types;
 
-  return 1;
+  return ret;
 }
 
 /* Make sure the memory operand we've been dealt is valid.

-- 
Alan Modra
Australia Development Lab, IBM


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]