Add support for RX V2 Instruction Set
[deliverable/binutils-gdb.git] / gas / read.c
index 2b37173c3e45a165373581c6fdeee8681ee7043b..b25ab8dee1a4ef1e29504b4fafd1ac328553b749 100644 (file)
@@ -1,7 +1,5 @@
 /* read.c - read a source file -
-   Copyright 1986, 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
-   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
-   2010, 2011, 2012  Free Software Foundation, Inc.
+   Copyright (C) 1986-2015 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
@@ -43,7 +41,7 @@
 #include "wchar.h"
 
 #ifndef TC_START_LABEL
-#define TC_START_LABEL(x,y,z) (x == ':')
+#define TC_START_LABEL(STR, NUL_CHAR, NEXT_CHAR) (NEXT_CHAR == ':')
 #endif
 
 /* Set by the object-format or the target.  */
@@ -244,9 +242,6 @@ static void do_align (int, char *, int, int);
 static void s_align (int, int);
 static void s_altmacro (int);
 static void s_bad_end (int);
-#ifdef OBJ_ELF
-static void s_gnu_attribute (int);
-#endif
 static void s_reloc (int);
 static int hex_float (int, char *);
 static segT get_known_segmented_expression (expressionS * expP);
@@ -268,8 +263,11 @@ read_begin (void)
   obstack_begin (&notes, chunksize);
   obstack_begin (&cond_obstack, chunksize);
 
+#ifndef tc_line_separator_chars
+#define tc_line_separator_chars line_separator_chars
+#endif
   /* Use machine dependent syntax.  */
-  for (p = line_separator_chars; *p; p++)
+  for (p = tc_line_separator_chars; *p; p++)
     is_end_of_line[(unsigned char) *p] = 2;
   /* Use more.  FIXME-SOMEDAY.  */
 
@@ -378,9 +376,6 @@ static const pseudo_typeS potable[] = {
   {"func", s_func, 0},
   {"global", s_globl, 0},
   {"globl", s_globl, 0},
-#ifdef OBJ_ELF
-  {"gnu_attribute", s_gnu_attribute, 0},
-#endif
   {"hword", cons, 2},
   {"if", s_if, (int) O_ne},
   {"ifb", s_ifb, 1},
@@ -562,10 +557,11 @@ pobegin (void)
   cfi_pop_insert ();
 }
 \f
-#define HANDLE_CONDITIONAL_ASSEMBLY()                                  \
+#define HANDLE_CONDITIONAL_ASSEMBLY(num_read)                          \
   if (ignore_input ())                                                 \
     {                                                                  \
-      char *eol = find_end_of_line (input_line_pointer, flag_m68k_mri); \
+      char *eol = find_end_of_line (input_line_pointer - (num_read),   \
+                                   flag_m68k_mri);                     \
       input_line_pointer = (input_line_pointer <= buffer_limit         \
                            && eol >= buffer_limit)                     \
                           ? buffer_limit                               \
@@ -745,7 +741,8 @@ single instruction is %u bytes long but .bundle_align_mode limit is %u"),
 void
 read_a_source_file (char *name)
 {
-  char c;
+  char nul_char;
+  char next_char;
   char *s;             /* String of symbol, '\0' appended.  */
   int temp;
   pseudo_typeS *pop;
@@ -832,16 +829,18 @@ read_a_source_file (char *name)
 
              if (LABELS_WITHOUT_COLONS || flag_m68k_mri)
                {
+                 next_char = * input_line_pointer;
                  /* Text at the start of a line must be a label, we
                     run down and stick a colon in.  */
-                 if (is_name_beginner (*input_line_pointer))
+                 if (is_name_beginner (next_char) || next_char == '"')
                    {
-                     char *line_start = input_line_pointer;
+                     char *line_start;
                      int mri_line_macro;
 
-                     HANDLE_CONDITIONAL_ASSEMBLY ();
+                     HANDLE_CONDITIONAL_ASSEMBLY (0);
 
-                     c = get_symbol_end ();
+                     nul_char = get_symbol_name (& line_start);
+                     next_char = (nul_char == '"' ? input_line_pointer[1] : nul_char);
 
                      /* In MRI mode, the EQU and MACRO pseudoops must
                         be handled specially.  */
@@ -875,8 +874,7 @@ read_a_source_file (char *name)
                         symbol in the symbol table.  */
                      if (!mri_line_macro
 #ifdef TC_START_LABEL_WITHOUT_COLON
-                         && TC_START_LABEL_WITHOUT_COLON(c,
-                                                         input_line_pointer)
+                         && TC_START_LABEL_WITHOUT_COLON (nul_char, next_char)
 #endif
                          )
                        line_label = colon (line_start);
@@ -886,8 +884,8 @@ read_a_source_file (char *name)
                                                    (valueT) 0,
                                                    &zero_address_frag);
 
-                     *input_line_pointer = c;
-                     if (c == ':')
+                     next_char = restore_line_pointer (nul_char);
+                     if (next_char == ':')
                        input_line_pointer++;
                    }
                }
@@ -902,30 +900,32 @@ read_a_source_file (char *name)
             Each test is independent of all other tests at the (top)
             level.  */
          do
-           c = *input_line_pointer++;
-         while (c == '\t' || c == ' ' || c == '\f');
+           nul_char = next_char = *input_line_pointer++;
+         while (next_char == '\t' || next_char == ' ' || next_char == '\f');
 
          /* C is the 1st significant character.
             Input_line_pointer points after that character.  */
-         if (is_name_beginner (c))
+         if (is_name_beginner (next_char) || next_char == '"')
            {
+             char *rest;
+
              /* Want user-defined label or pseudo/opcode.  */
-             HANDLE_CONDITIONAL_ASSEMBLY ();
+             HANDLE_CONDITIONAL_ASSEMBLY (1);
 
-             s = --input_line_pointer;
-             c = get_symbol_end ();    /* name's delimiter.  */
+             --input_line_pointer;
+             nul_char = get_symbol_name (& s); /* name's delimiter.  */
+             next_char = (nul_char == '"' ? input_line_pointer[1] : nul_char);
+             rest = input_line_pointer + (nul_char == '"' ? 2 : 1);
 
-             /* C is character after symbol.
-                That character's place in the input line is now '\0'.
+             /* NEXT_CHAR is character after symbol.
+                The end of symbol in the input line is now '\0'.
                 S points to the beginning of the symbol.
                   [In case of pseudo-op, s->'.'.]
-                Input_line_pointer->'\0' where c was.  */
-             if (TC_START_LABEL (c, s, input_line_pointer))
+                Input_line_pointer->'\0' where NUL_CHAR was.  */
+             if (TC_START_LABEL (s, nul_char, next_char))
                {
                  if (flag_m68k_mri)
                    {
-                     char *rest = input_line_pointer + 1;
-
                      /* In MRI mode, \tsym: set 0 is permitted.  */
                      if (*rest == ':')
                        ++rest;
@@ -944,27 +944,27 @@ read_a_source_file (char *name)
                    }
 
                  line_label = colon (s);       /* User-defined label.  */
-                 /* Put ':' back for error messages' sake.  */
-                 *input_line_pointer++ = ':';
+                 restore_line_pointer (nul_char);
+                 ++ input_line_pointer;
 #ifdef tc_check_label
                  tc_check_label (line_label);
 #endif
                  /* Input_line_pointer->after ':'.  */
                  SKIP_WHITESPACE ();
                }
-             else if ((c == '=' && input_line_pointer[1] == '=')
-                      || ((c == ' ' || c == '\t')
-                          && input_line_pointer[1] == '='
-                          && input_line_pointer[2] == '='))
+             else if ((next_char == '=' && *rest == '=')
+                      || ((next_char == ' ' || next_char == '\t')
+                          && rest[0] == '='
+                          && rest[1] == '='))
                {
                  equals (s, -1);
                  demand_empty_rest_of_line ();
                }
-             else if ((c == '='
-                      || ((c == ' ' || c == '\t')
-                           && input_line_pointer[1] == '='))
+             else if ((next_char == '='
+                      || ((next_char == ' ' || next_char == '\t')
+                           && *rest == '='))
 #ifdef TC_EQUAL_IN_INSN
-                          && !TC_EQUAL_IN_INSN (c, s)
+                          && !TC_EQUAL_IN_INSN (next_char, s)
 #endif
                           )
                {
@@ -1004,7 +1004,7 @@ read_a_source_file (char *name)
                    {
                      /* PSEUDO - OP.
 
-                        WARNING: c has next char, which may be end-of-line.
+                        WARNING: next_char may be end-of-line.
                         We lookup the pseudo-op table with s+1 because we
                         already know that the pseudo-op begins with a '.'.  */
 
@@ -1049,25 +1049,25 @@ read_a_source_file (char *name)
                        {
                          char *end = input_line_pointer;
 
-                         *input_line_pointer = c;
+                         (void) restore_line_pointer (nul_char);
                          s_ignore (0);
-                         c = *--input_line_pointer;
+                         nul_char = next_char = *--input_line_pointer;
                          *input_line_pointer = '\0';
-                         if (! macro_defined || ! try_macro (c, s))
+                         if (! macro_defined || ! try_macro (next_char, s))
                            {
                              *end = '\0';
                              as_bad (_("unknown pseudo-op: `%s'"), s);
-                             *input_line_pointer++ = c;
+                             *input_line_pointer++ = nul_char;
                            }
                          continue;
                        }
 
                      /* Put it back for error messages etc.  */
-                     *input_line_pointer = c;
+                     next_char = restore_line_pointer (nul_char);
                      /* The following skip of whitespace is compulsory.
                         A well shaped space is sometimes all that separates
                         keyword from operands.  */
-                     if (c == ' ' || c == '\t')
+                     if (next_char == ' ' || next_char == '\t')
                        input_line_pointer++;
 
                      /* Input_line is restored.
@@ -1081,16 +1081,16 @@ read_a_source_file (char *name)
                    }
                  else
                    {
-                     /* WARNING: c has char, which may be end-of-line.  */
-                     /* Also: input_line_pointer->`\0` where c was.  */
-                     *input_line_pointer = c;
+                     /* WARNING: next_char may be end-of-line.  */
+                     /* Also: input_line_pointer->`\0` where nul_char was.  */
+                     (void) restore_line_pointer (nul_char);
                      input_line_pointer = _find_end_of_line (input_line_pointer, flag_m68k_mri, 1, 0);
-                     c = *input_line_pointer;
+                     next_char = nul_char = *input_line_pointer;
                      *input_line_pointer = '\0';
 
                      generate_lineno_debug ();
 
-                     if (macro_defined && try_macro (c, s))
+                     if (macro_defined && try_macro (next_char, s))
                        continue;
 
                      if (mri_pending_align)
@@ -1106,7 +1106,7 @@ read_a_source_file (char *name)
 
                      assemble_one (s); /* Assemble 1 instruction.  */
 
-                     *input_line_pointer++ = c;
+                     *input_line_pointer++ = nul_char;
 
                      /* We resume loop AFTER the end-of-line from
                         this instruction.  */
@@ -1116,17 +1116,20 @@ read_a_source_file (char *name)
            }
 
          /* Empty statement?  */
-         if (is_end_of_line[(unsigned char) c])
+         if (is_end_of_line[(unsigned char) next_char])
            continue;
 
-         if ((LOCAL_LABELS_DOLLAR || LOCAL_LABELS_FB) && ISDIGIT (c))
+         if ((LOCAL_LABELS_DOLLAR || LOCAL_LABELS_FB) && ISDIGIT (next_char))
            {
              /* local label  ("4:")  */
              char *backup = input_line_pointer;
 
-             HANDLE_CONDITIONAL_ASSEMBLY ();
+             HANDLE_CONDITIONAL_ASSEMBLY (1);
+
+             temp = next_char - '0';
 
-             temp = c - '0';
+             if (nul_char == '"')
+               ++ input_line_pointer;
 
              /* Read the whole number.  */
              while (ISDIGIT (*input_line_pointer))
@@ -1160,9 +1163,9 @@ read_a_source_file (char *name)
                }
 
              input_line_pointer = backup;
-           }                   /* local label  ("4:") */
+           }
 
-         if (c && strchr (line_comment_chars, c))
+         if (next_char && strchr (line_comment_chars, next_char))
            {                   /* Its a comment.  Better say APP or NO_APP.  */
              sb sbuf;
              char *ends;
@@ -1181,7 +1184,6 @@ read_a_source_file (char *name)
              bump_line_counters ();
              s += 4;
 
-             sb_new (&sbuf);
              ends = strstr (s, "#NO_APP\n");
 
              if (!ends)
@@ -1262,7 +1264,9 @@ read_a_source_file (char *name)
                 actual macro expansion (possibly nested) and other
                 input expansion work.  Beware that in messages, line
                 numbers and possibly file names will be incorrect.  */
-             sb_add_string (&sbuf, new_buf);
+             new_length = strlen (new_buf);
+             sb_build (&sbuf, new_length);
+             sb_add_buffer (&sbuf, new_buf, new_length);
              input_scrub_include_sb (&sbuf, input_line_pointer, 0);
              sb_kill (&sbuf);
              buffer_limit = input_scrub_next_buffer (&input_line_pointer);
@@ -1270,10 +1274,10 @@ read_a_source_file (char *name)
              continue;
            }
 
-         HANDLE_CONDITIONAL_ASSEMBLY ();
+         HANDLE_CONDITIONAL_ASSEMBLY (1);
 
 #ifdef tc_unrecognized_line
-         if (tc_unrecognized_line (c))
+         if (tc_unrecognized_line (next_char))
            continue;
 #endif
          input_line_pointer--;
@@ -1311,10 +1315,10 @@ read_a_source_file (char *name)
 }
 
 /* Convert O_constant expression EXP into the equivalent O_big representation.
-   Take the sign of the number from X_unsigned rather than X_add_number.  */
+   Take the sign of the number from SIGN rather than X_add_number.  */
 
 static void
-convert_to_bignum (expressionS *exp)
+convert_to_bignum (expressionS *exp, int sign)
 {
   valueT value;
   unsigned int i;
@@ -1327,12 +1331,20 @@ convert_to_bignum (expressionS *exp)
     }
   /* Add a sequence of sign bits if the top bit of X_add_number is not
      the sign of the original value.  */
-  if ((exp->X_add_number < 0) != !exp->X_unsigned)
-    generic_bignum[i++] = exp->X_unsigned ? 0 : LITTLENUM_MASK;
+  if ((exp->X_add_number < 0) == !sign)
+    generic_bignum[i++] = sign ? LITTLENUM_MASK : 0;
   exp->X_op = O_big;
   exp->X_add_number = i;
 }
 
+static bfd_boolean
+in_bss (void)
+{
+  flagword flags = bfd_get_section_flags (stdoutput, now_seg);
+
+  return (flags & SEC_ALLOC) && !(flags & (SEC_LOAD | SEC_HAS_CONTENTS));
+}
+
 /* For most MRI pseudo-ops, the line actually ends at the first
    nonquoted space.  This function looks for that point, stuffs a null
    in, and sets *STOPCP to the character that used to be there, and
@@ -1398,13 +1410,17 @@ s_abort (int ignore ATTRIBUTE_UNUSED)
 static void
 do_align (int n, char *fill, int len, int max)
 {
-  if (now_seg == absolute_section)
+  if (now_seg == absolute_section || in_bss ())
     {
       if (fill != NULL)
        while (len-- > 0)
          if (*fill++ != '\0')
            {
-             as_warn (_("ignoring fill value in absolute section"));
+             if (now_seg == absolute_section)
+               as_warn (_("ignoring fill value in absolute section"));
+             else
+               as_warn (_("ignoring fill value in section `%s'"),
+                        segment_name (now_seg));
              break;
            }
       fill = NULL;
@@ -1474,6 +1490,11 @@ s_align (int arg, int bytes_p)
     {
       align = get_absolute_expression ();
       SKIP_WHITESPACE ();
+
+#ifdef TC_ALIGN_ZERO_IS_DEFAULT
+      if (arg > 0 && align == 0)
+       align = arg;
+#endif
     }
 
   if (bytes_p)
@@ -1582,7 +1603,7 @@ s_align_ptwo (int arg)
 
 /* Switch in and out of alternate macro mode.  */
 
-void
+static void
 s_altmacro (int on)
 {
   demand_empty_rest_of_line ();
@@ -1603,7 +1624,7 @@ s_altmacro (int on)
    If a symbol name could not be read, the routine issues an error
    messages, skips to the end of the line and returns NULL.  */
 
-static char *
+char *
 read_symbol_name (void)
 {
   char * name;
@@ -1635,7 +1656,7 @@ read_symbol_name (void)
              name_end = start + len;
              name = start + sofar;
            }
-         
+
          *name++ = (char) C;
        }
       *name = 0;
@@ -1677,7 +1698,7 @@ read_symbol_name (void)
       ignore_rest_of_line ();
       return NULL;
     }
-    
+
   SKIP_WHITESPACE ();
 
   return start;
@@ -1708,7 +1729,7 @@ s_comm_internal (int param,
 
   temp = get_absolute_expr (&exp);
   size = temp;
-  size &= ((offsetT) 2 << (stdoutput->arch_info->bits_per_address - 1)) - 1;
+  size &= ((addressT) 2 << (stdoutput->arch_info->bits_per_address - 1)) - 1;
   if (exp.X_op == O_absent)
     {
       as_bad (_("missing size expression"));
@@ -1798,7 +1819,7 @@ s_mri_common (int small ATTRIBUTE_UNUSED)
 
   name = input_line_pointer;
   if (!ISDIGIT (*name))
-    c = get_symbol_end ();
+    c = get_symbol_name (& name);
   else
     {
       do
@@ -1821,7 +1842,7 @@ s_mri_common (int small ATTRIBUTE_UNUSED)
     }
 
   sym = symbol_find_or_make (name);
-  *input_line_pointer = c;
+  c = restore_line_pointer (c);
   if (alc != NULL)
     free (alc);
 
@@ -2198,6 +2219,20 @@ s_fill (int ignore ATTRIBUTE_UNUSED)
 
   if (size && !need_pass_2)
     {
+      if (now_seg == absolute_section)
+       {
+         if (rep_exp.X_op != O_constant)
+           as_bad (_("non-constant fill count for absolute section"));
+         else if (fill && rep_exp.X_add_number != 0)
+           as_bad (_("attempt to fill absolute section with non-zero value"));
+         abs_section_offset += rep_exp.X_add_number * size;
+       }
+      else if (fill
+              && (rep_exp.X_op != O_constant || rep_exp.X_add_number != 0)
+              && in_bss ())
+       as_bad (_("attempt to fill section `%s' with non-zero value"),
+               segment_name (now_seg));
+
       if (rep_exp.X_op == O_constant)
        {
          p = frag_var (rs_fill, (int) size, (int) size,
@@ -2291,139 +2326,6 @@ s_globl (int ignore ATTRIBUTE_UNUSED)
     mri_comment_end (stop, stopc);
 }
 
-#ifdef OBJ_ELF
-#define skip_whitespace(str)  do { if (*(str) == ' ') ++(str); } while (0)
-
-static inline int
-skip_past_char (char ** str, char c)
-{
-  if (**str == c)
-    {
-      (*str)++;
-      return 0;
-    }
-  else
-    return -1;
-}
-#define skip_past_comma(str) skip_past_char (str, ',')
-
-/* Parse an attribute directive for VENDOR.
-   Returns the attribute number read, or zero on error.  */
-int
-s_vendor_attribute (int vendor)
-{
-  expressionS exp;
-  int type;
-  int tag;
-  unsigned int i = 0;
-  char *s = NULL;
-
-  /* Read the first number or name.  */
-  skip_whitespace (input_line_pointer);
-  s = input_line_pointer;
-  if (ISDIGIT (*input_line_pointer))
-    {
-      expression (& exp);
-      if (exp.X_op != O_constant)
-       goto bad;
-      tag = exp.X_add_number;
-    }
-  else
-    {
-      char *name;
-
-      /* A name may contain '_', but no other punctuation.  */
-      for (; ISALNUM (*input_line_pointer) || *input_line_pointer == '_';
-          ++input_line_pointer)
-       i++;
-      if (i == 0)
-       goto bad;
-
-      name = (char *) alloca (i + 1);
-      memcpy (name, s, i);
-      name[i] = '\0';
-
-#ifndef CONVERT_SYMBOLIC_ATTRIBUTE
-#define CONVERT_SYMBOLIC_ATTRIBUTE(a) -1
-#endif
-
-      tag = CONVERT_SYMBOLIC_ATTRIBUTE (name);
-      if (tag == -1)
-       {
-         as_bad (_("Attribute name not recognised: %s"), name);
-         ignore_rest_of_line ();
-         return 0;
-       }
-    }
-
-  type = _bfd_elf_obj_attrs_arg_type (stdoutput, vendor, tag);
-
-  if (skip_past_comma (&input_line_pointer) == -1)
-    goto bad;
-  if (type & 1)
-    {
-      expression (& exp);
-      if (exp.X_op != O_constant)
-       {
-         as_bad (_("expected numeric constant"));
-         ignore_rest_of_line ();
-         return 0;
-       }
-      i = exp.X_add_number;
-    }
-  if ((type & 3) == 3
-      && skip_past_comma (&input_line_pointer) == -1)
-    {
-      as_bad (_("expected comma"));
-      ignore_rest_of_line ();
-      return 0;
-    }
-  if (type & 2)
-    {
-      int len;
-
-      skip_whitespace (input_line_pointer);
-      if (*input_line_pointer != '"')
-       goto bad_string;
-      s = demand_copy_C_string (&len);
-    }
-
-  switch (type & 3)
-    {
-    case 3:
-      bfd_elf_add_obj_attr_int_string (stdoutput, vendor, tag, i, s);
-      break;
-    case 2:
-      bfd_elf_add_obj_attr_string (stdoutput, vendor, tag, s);
-      break;
-    case 1:
-      bfd_elf_add_obj_attr_int (stdoutput, vendor, tag, i);
-      break;
-    default:
-      abort ();
-    }
-
-  demand_empty_rest_of_line ();
-  return tag;
-bad_string:
-  as_bad (_("bad string constant"));
-  ignore_rest_of_line ();
-  return 0;
-bad:
-  as_bad (_("expected <tag> , <value>"));
-  ignore_rest_of_line ();
-  return 0;
-}
-
-/* Parse a .gnu_attribute directive.  */
-
-static void
-s_gnu_attribute (int ignored ATTRIBUTE_UNUSED)
-{
-  s_vendor_attribute (OBJ_ATTR_GNU);
-}
-#endif /* OBJ_ELF */
-
 /* Handle the MRI IRP and IRPC pseudo-ops.  */
 
 void
@@ -2437,8 +2339,8 @@ s_irp (int irpc)
 
   as_where (&file, &line);
 
-  sb_new (&s);
   eol = find_end_of_line (input_line_pointer, 0);
+  sb_build (&s, eol - input_line_pointer);
   sb_add_buffer (&s, input_line_pointer, eol - input_line_pointer);
   input_line_pointer = eol;
 
@@ -2474,8 +2376,7 @@ s_linkonce (int ignore ATTRIBUTE_UNUSED)
       char *s;
       char c;
 
-      s = input_line_pointer;
-      c = get_symbol_end ();
+      c = get_symbol_name (& s);
       if (strcasecmp (s, "discard") == 0)
        type = LINKONCE_DISCARD;
       else if (strcasecmp (s, "one_only") == 0)
@@ -2487,7 +2388,7 @@ s_linkonce (int ignore ATTRIBUTE_UNUSED)
       else
        as_warn (_("unrecognized .linkonce type `%s'"), s);
 
-      *input_line_pointer = c;
+      (void) restore_line_pointer (c);
     }
 
 #ifdef obj_handle_link_once
@@ -2773,17 +2674,20 @@ s_macro (int ignore ATTRIBUTE_UNUSED)
 
   as_where (&file, &line);
 
-  sb_new (&s);
   eol = find_end_of_line (input_line_pointer, 0);
+  sb_build (&s, eol - input_line_pointer);
   sb_add_buffer (&s, input_line_pointer, eol - input_line_pointer);
   input_line_pointer = eol;
 
   if (line_label != NULL)
     {
       sb label;
+      size_t len;
 
-      sb_new (&label);
-      sb_add_string (&label, S_GET_NAME (line_label));
+      name = S_GET_NAME (line_label);
+      len = strlen (name);
+      sb_build (&label, len);
+      sb_add_buffer (&label, name, len);
       err = define_macro (0, &s, &label, get_macro_line_sb, file, line, &name);
       sb_kill (&label);
     }
@@ -2899,6 +2803,10 @@ do_org (segT segment, expressionS *exp, int fill)
       symbolS *sym = exp->X_add_symbol;
       offsetT off = exp->X_add_number * OCTETS_PER_BYTE;
 
+      if (fill && in_bss ())
+       as_warn (_("ignoring fill value in section `%s'"),
+                segment_name (now_seg));
+
       if (exp->X_op != O_constant && exp->X_op != O_symbol)
        {
          /* Handle complex expressions.  */
@@ -2978,7 +2886,7 @@ s_mri_sect (char *type ATTRIBUTE_UNUSED)
 
   name = input_line_pointer;
   if (!ISDIGIT (*name))
-    c = get_symbol_end ();
+    c = get_symbol_name (& name);
   else
     {
       do
@@ -2993,11 +2901,11 @@ s_mri_sect (char *type ATTRIBUTE_UNUSED)
 
   name = xstrdup (name);
 
-  *input_line_pointer = c;
+  c = restore_line_pointer (c);
 
   seg = subseg_new (name, 0);
 
-  if (*input_line_pointer == ',')
+  if (c == ',')
     {
       int align;
 
@@ -3052,16 +2960,15 @@ s_mri_sect (char *type ATTRIBUTE_UNUSED)
 
   SKIP_WHITESPACE ();
 
-  name = input_line_pointer;
-  c = get_symbol_end ();
+  c = get_symbol_name (& name);
 
   name = xstrdup (name);
 
-  *input_line_pointer = c;
+  c = restore_line_pointer (c);
 
   seg = subseg_new (name, 0);
 
-  if (*input_line_pointer != ',')
+  if (c != ',')
     *type = 'C';
   else
     {
@@ -3069,8 +2976,7 @@ s_mri_sect (char *type ATTRIBUTE_UNUSED)
 
       ++input_line_pointer;
       SKIP_WHITESPACE ();
-      sectype = input_line_pointer;
-      c = get_symbol_end ();
+      c = get_symbol_name (& sectype);
       if (*sectype == '\0')
        *type = 'C';
       else if (strcasecmp (sectype, "text") == 0)
@@ -3081,7 +2987,7 @@ s_mri_sect (char *type ATTRIBUTE_UNUSED)
        *type = 'R';
       else
        as_warn (_("unrecognized section type `%s'"), sectype);
-      *input_line_pointer = c;
+      (void) restore_line_pointer (c);
     }
 
   if (*input_line_pointer == ',')
@@ -3090,8 +2996,7 @@ s_mri_sect (char *type ATTRIBUTE_UNUSED)
 
       ++input_line_pointer;
       SKIP_WHITESPACE ();
-      seccmd = input_line_pointer;
-      c = get_symbol_end ();
+      c = get_symbol_name (& seccmd);
       if (strcasecmp (seccmd, "absolute") == 0)
        {
          as_bad (_("absolute sections are not supported"));
@@ -3103,14 +3008,14 @@ s_mri_sect (char *type ATTRIBUTE_UNUSED)
        {
          int align;
 
-         *input_line_pointer = c;
+         (void) restore_line_pointer (c);
          align = get_absolute_expression ();
          record_alignment (seg, align);
        }
       else
        {
          as_warn (_("unrecognized section command `%s'"), seccmd);
-         *input_line_pointer = c;
+         (void) restore_line_pointer (c);
        }
     }
 
@@ -3156,11 +3061,10 @@ s_purgem (int ignore ATTRIBUTE_UNUSED)
       char c;
 
       SKIP_WHITESPACE ();
-      name = input_line_pointer;
-      c = get_symbol_end ();
+      c = get_symbol_name (& name);
       delete_macro (name);
       *input_line_pointer = c;
-      SKIP_WHITESPACE ();
+      SKIP_WHITESPACE_AFTER_NAME ();
     }
   while (*input_line_pointer++ == ',');
 
@@ -3207,7 +3111,7 @@ do_repeat (int count, const char *start, const char *end)
       return;
     }
 
-  sb_new (&many);
+  sb_build (&many, count * one.len);
   while (count-- > 0)
     sb_add_sb (&many, &one);
 
@@ -3247,7 +3151,7 @@ do_repeat_with_expander (int count,
          char * sub;
          sb processed;
 
-         sb_new (& processed);
+         sb_build (& processed, one.len);
          sb_add_sb (& processed, & one);
          sub = strstr (processed.ptr, expander);
          len = sprintf (sub, "%d", count);
@@ -3321,7 +3225,7 @@ assign_symbol (char *name, int mode)
          symbol_set_frag (symbolP, dummy_frag);
        }
 #endif
-#ifdef OBJ_COFF
+#if defined (OBJ_COFF) && !defined (TE_PE)
       /* "set" symbols are local unless otherwise specified.  */
       SF_SET_LOCAL (symbolP);
 #endif
@@ -3457,10 +3361,11 @@ s_space (int mult)
       val.X_add_number = 0;
     }
 
-  if (val.X_op != O_constant
-      || val.X_add_number < - 0x80
-      || val.X_add_number > 0xff
-      || (mult != 0 && mult != 1 && val.X_add_number != 0))
+  if ((val.X_op != O_constant
+       || val.X_add_number < - 0x80
+       || val.X_add_number > 0xff
+       || (mult != 0 && mult != 1 && val.X_add_number != 0))
+      && (now_seg != absolute_section && !in_bss ()))
     {
       resolve_expression (&exp);
       if (exp.X_op != O_constant)
@@ -3501,6 +3406,8 @@ s_space (int mult)
          /* If we are in the absolute section, just bump the offset.  */
          if (now_seg == absolute_section)
            {
+             if (val.X_op != O_constant || val.X_add_number != 0)
+               as_warn (_("ignoring fill value in absolute section"));
              abs_section_offset += repeat;
              goto getout;
            }
@@ -3538,7 +3445,10 @@ s_space (int mult)
                          make_expr_symbol (&exp), (offsetT) 0, (char *) 0);
        }
 
-      if (p)
+      if ((val.X_op != O_constant || val.X_add_number != 0) && in_bss ())
+       as_warn (_("ignoring fill value in section `%s'"),
+                segment_name (now_seg));
+      else if (p)
        *p = val.X_add_number;
     }
 
@@ -3985,19 +3895,22 @@ parse_mri_cons (expressionS *exp, unsigned int nbytes);
 
 #ifndef TC_PARSE_CONS_EXPRESSION
 #ifdef BITFIELD_CONS_EXPRESSIONS
-#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_bitfield_cons (EXP, NBYTES)
+#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \
+  (parse_bitfield_cons (EXP, NBYTES), TC_PARSE_CONS_RETURN_NONE)
 static void
 parse_bitfield_cons (expressionS *exp, unsigned int nbytes);
 #endif
 #ifdef REPEAT_CONS_EXPRESSIONS
-#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) parse_repeat_cons (EXP, NBYTES)
+#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \
+  (parse_repeat_cons (EXP, NBYTES), TC_PARSE_CONS_RETURN_NONE)
 static void
 parse_repeat_cons (expressionS *exp, unsigned int nbytes);
 #endif
 
 /* If we haven't gotten one yet, just call expression.  */
 #ifndef TC_PARSE_CONS_EXPRESSION
-#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) expression (EXP)
+#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \
+  (expression (EXP), TC_PARSE_CONS_RETURN_NONE)
 #endif
 #endif
 
@@ -4005,7 +3918,7 @@ void
 do_parse_cons_expression (expressionS *exp,
                          int nbytes ATTRIBUTE_UNUSED)
 {
-  TC_PARSE_CONS_EXPRESSION (exp, nbytes);
+  (void) TC_PARSE_CONS_EXPRESSION (exp, nbytes);
 }
 
 
@@ -4048,19 +3961,29 @@ cons_worker (int nbytes,        /* 1=.byte, 2=.word, 4=.long.  */
   c = 0;
   do
     {
+      TC_PARSE_CONS_RETURN_TYPE ret = TC_PARSE_CONS_RETURN_NONE;
+#ifdef TC_CONS_FIX_CHECK
+      fixS **cur_fix = &frchain_now->fix_tail;
+
+      if (*cur_fix != NULL)
+       cur_fix = &(*cur_fix)->fx_next;
+#endif
+
 #ifdef TC_M68K
       if (flag_m68k_mri)
        parse_mri_cons (&exp, (unsigned int) nbytes);
       else
 #endif
        {
+#if 0
          if (*input_line_pointer == '"')
            {
              as_bad (_("unexpected `\"' in expression"));
              ignore_rest_of_line ();
              return;
            }
-         TC_PARSE_CONS_EXPRESSION (&exp, (unsigned int) nbytes);
+#endif
+         ret = TC_PARSE_CONS_EXPRESSION (&exp, (unsigned int) nbytes);
        }
 
       if (rva)
@@ -4070,7 +3993,10 @@ cons_worker (int nbytes, /* 1=.byte, 2=.word, 4=.long.  */
          else
            as_fatal (_("rva without symbol"));
        }
-      emit_expr (&exp, (unsigned int) nbytes);
+      emit_expr_with_reloc (&exp, (unsigned int) nbytes, ret);
+#ifdef TC_CONS_FIX_CHECK
+      TC_CONS_FIX_CHECK (&exp, nbytes, *cur_fix);
+#endif
       ++c;
     }
   while (*input_line_pointer++ == ',');
@@ -4103,7 +4029,7 @@ s_rva (int size)
 
 /* .reloc offset, reloc_name, symbol+addend.  */
 
-void
+static void
 s_reloc (int ignore ATTRIBUTE_UNUSED)
 {
   char *stop = NULL;
@@ -4112,6 +4038,14 @@ s_reloc (int ignore ATTRIBUTE_UNUSED)
   char *r_name;
   int c;
   struct reloc_list *reloc;
+  struct _bfd_rel { char *name; bfd_reloc_code_real_type code; };
+  static struct _bfd_rel bfd_relocs[] = {
+    { "NONE", BFD_RELOC_NONE },
+    { "8", BFD_RELOC_8 },
+    { "16", BFD_RELOC_16 },
+    { "32", BFD_RELOC_32 },
+    { "64", BFD_RELOC_64 }
+  };
 
   reloc = (struct reloc_list *) xmalloc (sizeof (*reloc));
 
@@ -4152,9 +4086,21 @@ s_reloc (int ignore ATTRIBUTE_UNUSED)
 
   ++input_line_pointer;
   SKIP_WHITESPACE ();
-  r_name = input_line_pointer;
-  c = get_symbol_end ();
-  reloc->u.a.howto = bfd_reloc_name_lookup (stdoutput, r_name);
+  c = get_symbol_name (& r_name);
+  if (strncasecmp (r_name, "BFD_RELOC_", 10) == 0)
+    {
+      unsigned int i;
+
+      for (reloc->u.a.howto = NULL, i = 0; i < ARRAY_SIZE (bfd_relocs); i++)
+       if (strcasecmp (r_name + 10, bfd_relocs[i].name) == 0)
+         {
+           reloc->u.a.howto = bfd_reloc_type_lookup (stdoutput,
+                                                     bfd_relocs[i].code);
+           break;
+         }
+    }
+  else
+    reloc->u.a.howto = bfd_reloc_name_lookup (stdoutput, r_name);
   *input_line_pointer = c;
   if (reloc->u.a.howto == NULL)
     {
@@ -4163,7 +4109,7 @@ s_reloc (int ignore ATTRIBUTE_UNUSED)
     }
 
   exp.X_op = O_absent;
-  SKIP_WHITESPACE ();
+  SKIP_WHITESPACE_AFTER_NAME ();
   if (*input_line_pointer == ',')
     {
       ++input_line_pointer;
@@ -4213,6 +4159,14 @@ s_reloc (int ignore ATTRIBUTE_UNUSED)
 
 void
 emit_expr (expressionS *exp, unsigned int nbytes)
+{
+  emit_expr_with_reloc (exp, nbytes, TC_PARSE_CONS_RETURN_NONE);
+}
+
+void
+emit_expr_with_reloc (expressionS *exp,
+                     unsigned int nbytes,
+                     TC_PARSE_CONS_RETURN_TYPE reloc)
 {
   operatorT op;
   char *p;
@@ -4222,10 +4176,9 @@ emit_expr (expressionS *exp, unsigned int nbytes)
   if (need_pass_2)
     return;
 
-  /* Grow the current frag now so that dot_value does not get invalidated
-     if the frag were to fill up in the frag_more() call below.  */
   frag_grow (nbytes);
   dot_value = frag_now_fix ();
+  dot_frag = frag_now;
 
 #ifndef NO_LISTING
 #ifdef OBJ_ELF
@@ -4296,15 +4249,6 @@ emit_expr (expressionS *exp, unsigned int nbytes)
 
   op = exp->X_op;
 
-  /* Allow `.word 0' in the absolute section.  */
-  if (now_seg == absolute_section)
-    {
-      if (op != O_constant || exp->X_add_number != 0)
-       as_bad (_("attempt to store value in absolute section"));
-      abs_section_offset += nbytes;
-      return;
-    }
-
   /* Handle a negative bignum.  */
   if (op == O_uminus
       && exp->X_add_number == 0
@@ -4354,8 +4298,28 @@ emit_expr (expressionS *exp, unsigned int nbytes)
       op = O_constant;
     }
 
+  /* Allow `.word 0' in the absolute section.  */
+  if (now_seg == absolute_section)
+    {
+      if (op != O_constant || exp->X_add_number != 0)
+       as_bad (_("attempt to store value in absolute section"));
+      abs_section_offset += nbytes;
+      return;
+    }
+
+  /* Allow `.word 0' in BSS style sections.  */
+  if ((op != O_constant || exp->X_add_number != 0) && in_bss ())
+    as_bad (_("attempt to store non-zero value in section `%s'"),
+           segment_name (now_seg));
+
   p = frag_more ((int) nbytes);
 
+  if (reloc != TC_PARSE_CONS_RETURN_NONE)
+    {
+      emit_expr_fix (exp, nbytes, frag_now, p, reloc);
+      return;
+    }
+
 #ifndef WORKING_DOT_WORD
   /* If we have the difference of two symbols in a word, save it on
      the broken_words list.  See the code in write.c.  */
@@ -4386,7 +4350,7 @@ emit_expr (expressionS *exp, unsigned int nbytes)
   if (op == O_constant && nbytes > sizeof (valueT))
     {
       extra_digit = exp->X_unsigned ? 0 : -1;
-      convert_to_bignum (exp);
+      convert_to_bignum (exp, !exp->X_unsigned);
       op = O_big;
     }
 
@@ -4514,23 +4478,41 @@ emit_expr (expressionS *exp, unsigned int nbytes)
        }
     }
   else
-    emit_expr_fix (exp, nbytes, frag_now, p);
+    emit_expr_fix (exp, nbytes, frag_now, p, TC_PARSE_CONS_RETURN_NONE);
 }
 
 void
-emit_expr_fix (expressionS *exp, unsigned int nbytes, fragS *frag, char *p)
+emit_expr_fix (expressionS *exp, unsigned int nbytes, fragS *frag, char *p,
+              TC_PARSE_CONS_RETURN_TYPE r ATTRIBUTE_UNUSED)
 {
-  memset (p, 0, nbytes);
+  int offset = 0;
+  unsigned int size = nbytes;
+
+  memset (p, 0, size);
 
   /* Generate a fixS to record the symbol value.  */
 
 #ifdef TC_CONS_FIX_NEW
-  TC_CONS_FIX_NEW (frag, p - frag->fr_literal, nbytes, exp);
+  TC_CONS_FIX_NEW (frag, p - frag->fr_literal + offset, size, exp, r);
 #else
-  {
-    bfd_reloc_code_real_type r;
+  if (r != TC_PARSE_CONS_RETURN_NONE)
+    {
+      reloc_howto_type *reloc_howto;
+
+      reloc_howto = bfd_reloc_type_lookup (stdoutput, r);
+      size = bfd_get_reloc_size (reloc_howto);
 
-    switch (nbytes)
+      if (size > nbytes)
+       {
+         as_bad (_("%s relocations do not fit in %u bytes\n"),
+                 reloc_howto->name, nbytes);
+         return;
+       }
+      else if (target_big_endian)
+       offset = nbytes - size;
+    }
+  else
+    switch (size)
       {
       case 1:
        r = BFD_RELOC_8;
@@ -4548,13 +4530,11 @@ emit_expr_fix (expressionS *exp, unsigned int nbytes, fragS *frag, char *p)
        r = BFD_RELOC_64;
        break;
       default:
-       as_bad (_("unsupported BFD relocation size %u"), nbytes);
-       r = BFD_RELOC_32;
-       break;
+       as_bad (_("unsupported BFD relocation size %u"), size);
+       return;
       }
-    fix_new_exp (frag, p - frag->fr_literal, (int) nbytes, exp,
-                0, r);
-  }
+  fix_new_exp (frag, p - frag->fr_literal + offset, size,
+              exp, 0, r);
 #endif
 }
 \f
@@ -4663,7 +4643,7 @@ parse_bitfield_cons (exp, nbytes)
              return;
            }                   /* Too complex.  */
 
-         value |= ((~(-1 << width) & exp->X_add_number)
+         value |= ((~(-(1 << width)) & exp->X_add_number)
                    << ((BITS_PER_CHAR * nbytes) - bits_available));
 
          if ((bits_available -= width) == 0
@@ -4680,6 +4660,7 @@ parse_bitfield_cons (exp, nbytes)
       exp->X_add_number = value;
       exp->X_op = O_constant;
       exp->X_unsigned = 1;
+      exp->X_extrabit = 0;
     }
 }
 
@@ -4689,15 +4670,13 @@ parse_bitfield_cons (exp, nbytes)
 
 #ifdef TC_M68K
 static void
-parse_mri_cons (exp, nbytes)
-     expressionS *exp;
-     unsigned int nbytes;
+parse_mri_cons (expressionS *exp, unsigned int nbytes)
 {
   if (*input_line_pointer != '\''
       && (input_line_pointer[1] != '\''
          || (*input_line_pointer != 'A'
              && *input_line_pointer != 'E')))
-    TC_PARSE_CONS_EXPRESSION (exp, nbytes);
+    (void) TC_PARSE_CONS_EXPRESSION (exp, nbytes);
   else
     {
       unsigned int scan;
@@ -4916,6 +4895,21 @@ float_cons (/* Clobbers input_line-pointer, checks end-of-line.  */
       return;
     }
 
+  if (now_seg == absolute_section)
+    {
+      as_bad (_("attempt to store float in absolute section"));
+      ignore_rest_of_line ();
+      return;
+    }
+
+  if (in_bss ())
+    {
+      as_bad (_("attempt to store float in section `%s'"),
+             segment_name (now_seg));
+      ignore_rest_of_line ();
+      return;
+    }
+
 #ifdef md_flush_pending_output
   md_flush_pending_output ();
 #endif
@@ -5154,7 +5148,7 @@ output_big_sleb128 (char *p, LITTLENUM_TYPE *bignum, int size)
     {
       /* Sign-extend VAL.  */
       if (val & (1 << (loaded - 1)))
-       val |= ~0 << loaded;
+       val |= ~0U << loaded;
       if (orig)
        *p = val & 0x7f;
       p++;
@@ -5212,7 +5206,7 @@ output_big_leb128 (char *p, LITTLENUM_TYPE *bignum, int size, int sign)
 }
 
 /* Generate the appropriate fragments for a given expression to emit a
-   leb128 value.  */
+   leb128 value.  SIGN is 1 for sleb, 0 for uleb.  */
 
 static void
 emit_leb128_expr (expressionS *exp, int sign)
@@ -5239,15 +5233,27 @@ emit_leb128_expr (expressionS *exp, int sign)
     }
   else if (op == O_constant
           && sign
-          && (exp->X_add_number < 0) != !exp->X_unsigned)
+          && (exp->X_add_number < 0) == !exp->X_extrabit)
     {
       /* We're outputting a signed leb128 and the sign of X_add_number
         doesn't reflect the sign of the original value.  Convert EXP
         to a correctly-extended bignum instead.  */
-      convert_to_bignum (exp);
+      convert_to_bignum (exp, exp->X_extrabit);
       op = O_big;
     }
 
+  if (now_seg == absolute_section)
+    {
+      if (op != O_constant || exp->X_add_number != 0)
+       as_bad (_("attempt to store value in absolute section"));
+      abs_section_offset++;
+      return;
+    }
+
+  if ((op != O_constant || exp->X_add_number != 0) && in_bss ())
+    as_bad (_("attempt to store non-zero value in section `%s'"),
+           segment_name (now_seg));
+
   /* Let check_eh_frame know that data is being emitted.  nbytes == -1 is
      a signal that this is leb128 data.  It shouldn't optimize this away.  */
   nbytes = (unsigned int) -1;
@@ -5317,6 +5323,10 @@ s_leb128 (int sign)
 static void
 stringer_append_char (int c, int bitsize)
 {
+  if (c && in_bss ())
+    as_bad (_("attempt to store non-empty string in section `%s'"),
+           segment_name (now_seg));
+
   if (!target_big_endian)
     FRAG_APPEND_1_CHAR (c);
 
@@ -5372,6 +5382,15 @@ stringer (int bits_appendzero)
   md_cons_align (1);
 #endif
 
+  /* If we have been switched into the abs_section then we
+     will not have an obstack onto which we can hang strings.  */
+  if (now_seg == absolute_section)
+    {
+      as_bad (_("strings must be placed into a section"));
+      ignore_rest_of_line ();
+      return;
+    }
+
   /* The following awkward logic is to parse ZERO or more strings,
      comma separated. Recall a string expression includes spaces
      before the opening '\"' and spaces after the closing '\"'.
@@ -5386,14 +5405,6 @@ stringer (int bits_appendzero)
     {
       c = ',';                 /* Do loop.  */
     }
-  /* If we have been switched into the abs_section then we
-     will not have an obstack onto which we can hang strings.  */
-  if (now_seg == absolute_section)
-    {
-      as_bad (_("strings must be placed into a section"));
-      c = 0;
-      ignore_rest_of_line ();
-    }
 
   while (c == ',' || c == '<' || c == '"')
     {
@@ -5477,7 +5488,7 @@ next_char_of_string (void)
 
 #ifndef NO_STRING_ESCAPES
     case '\\':
-      switch (c = *input_line_pointer++)
+      switch (c = *input_line_pointer++ & CHAR_MASK)
        {
        case 'b':
          c = '\b';
@@ -5528,7 +5539,7 @@ next_char_of_string (void)
                number = number * 8 + c - '0';
              }
 
-           c = number & 0xff;
+           c = number & CHAR_MASK;
          }
          --input_line_pointer;
          break;
@@ -5550,7 +5561,7 @@ next_char_of_string (void)
                  number = number * 16 + c - 'a' + 10;
                c = *input_line_pointer++;
              }
-           c = number & 0xff;
+           c = number & CHAR_MASK;
            --input_line_pointer;
          }
          break;
@@ -5929,8 +5940,8 @@ add_include_dir (char *path)
     {
       include_dir_count++;
       include_dirs =
-       (char **) realloc (include_dirs,
-                          include_dir_count * sizeof (*include_dirs));
+       (char **) xrealloc (include_dirs,
+                           include_dir_count * sizeof (*include_dirs));
     }
 
   include_dirs[include_dir_count - 1] = path;  /* New one.  */
@@ -6022,11 +6033,10 @@ do_s_func (int end_p, const char *default_prefix)
          return;
        }
 
-      name = input_line_pointer;
-      delim1 = get_symbol_end ();
+      delim1 = get_symbol_name (& name);
       name = xstrdup (name);
       *input_line_pointer = delim1;
-      SKIP_WHITESPACE ();
+      SKIP_WHITESPACE_AFTER_NAME ();
       if (*input_line_pointer != ',')
        {
          if (default_prefix)
@@ -6052,10 +6062,9 @@ do_s_func (int end_p, const char *default_prefix)
        {
          ++input_line_pointer;
          SKIP_WHITESPACE ();
-         label = input_line_pointer;
-         delim2 = get_symbol_end ();
+         delim2 = get_symbol_name (& label);
          label = xstrdup (label);
-         *input_line_pointer = delim2;
+         restore_line_pointer (delim2);
        }
 
       if (debug_type == DEBUG_STABS)
@@ -6167,8 +6176,9 @@ void
 input_scrub_insert_line (const char *line)
 {
   sb newline;
-  sb_new (&newline);
-  sb_add_string (&newline, line);
+  size_t len = strlen (line);
+  sb_build (&newline, len);
+  sb_add_buffer (&newline, line, len);
   input_scrub_include_sb (&newline, input_line_pointer, 0);
   sb_kill (&newline);
   buffer_limit = input_scrub_next_buffer (&input_line_pointer);
@@ -6229,7 +6239,7 @@ _find_end_of_line (char *s, int mri_string, int insn ATTRIBUTE_UNUSED,
     }
   if (inquote)
     as_warn (_("missing closing `%c'"), inquote);
-  if (inescape)
+  if (inescape && !ignore_input ())
     as_warn (_("stray `\\'"));
   return s;
 }
This page took 0.04222 seconds and 4 git commands to generate.