]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gas: Revert PR 32391 related commits to fix 3 regressions
authorH.J. Lu <hjl.tools@gmail.com>
Wed, 1 Jan 2025 22:09:30 +0000 (06:09 +0800)
committerH.J. Lu <hjl.tools@gmail.com>
Thu, 2 Jan 2025 06:58:48 +0000 (14:58 +0800)
9f2e3c21f65 Fix the handling or arguments and macro pseudo-variables inside nested assembler macros.

introduced 3 regressions of PR gas/32484, PR gas/32486 and PR gas/32487.
Revert all PR 32391 related commits and add tests for PR gas/32484,
PR gas/32486, PR gas/32487.

PR gas/32484
PR gas/32486
PR gas/32487
* testsuite/gas/macros/macros.exp: Run nesting1, nesting2 and
nesting3.
* testsuite/gas/macros/nesting1.d: New file.
* testsuite/gas/macros/nesting1.s: Likewise.
* testsuite/gas/macros/nesting2.d: Likewise.
* testsuite/gas/macros/nesting2.s: Likewise.
* testsuite/gas/macros/nesting3.d: Likewise.
* testsuite/gas/macros/nesting3.s: Likewise.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
15 files changed:
gas/config/tc-iq2000.c
gas/doc/as.texi
gas/input-scrub.c
gas/macro.c
gas/macro.h
gas/read.c
gas/testsuite/gas/macros/macros.exp
gas/testsuite/gas/macros/nesting.d [deleted file]
gas/testsuite/gas/macros/nesting.s [deleted file]
gas/testsuite/gas/macros/nesting1.d [new file with mode: 0644]
gas/testsuite/gas/macros/nesting1.s [new file with mode: 0644]
gas/testsuite/gas/macros/nesting2.d [new file with mode: 0644]
gas/testsuite/gas/macros/nesting2.s [new file with mode: 0644]
gas/testsuite/gas/macros/nesting3.d [new file with mode: 0644]
gas/testsuite/gas/macros/nesting3.s [new file with mode: 0644]

index 8dc3b768e3a845824099daea94178303a48ff07c..c65f264528fbd14406d30e5e816884af902826fe 100644 (file)
@@ -105,6 +105,8 @@ struct iq2000_hi_fixup
 /* The list of unmatched HI relocs.  */
 static struct iq2000_hi_fixup * iq2000_hi_fixup_list;
 
+/* Macro hash table, which we will add to.  */
+extern struct htab *macro_hash;
 \f
 const char md_shortopts[] = "";
 const struct option md_longopts[] =
@@ -277,7 +279,9 @@ iq2000_add_macro (const char *  name,
        }
     }
 
-  (void) add_macro (macro, true);
+  str_hash_insert (macro_hash, macro->name, macro, 1);
+
+  macro_defined = 1;
 }
 
 static void
index 69d6d3c88b03ebe40c6cd136f5a131fba9decd74..c9f65a471257046c8b41803efd636735802c6e93 100644 (file)
@@ -6215,12 +6215,7 @@ With that definition, @samp{SUM 0,5} is equivalent to this assembly input:
 @item .macro @var{macname}
 @itemx .macro @var{macname} @var{macargs} @dots{}
 @cindex @code{macro} directive
-Begin the definition of a macro called @var{macname}.  Macro names are case
-insensitive.  Macro definitions can be nested, although their behaviour is
-sometimes counter intuitive.  Nested macros only have scope within their
-defining macro.
-
-If your macro
+Begin the definition of a macro called @var{macname}.  If your macro
 definition requires arguments, specify their names after the macro name,
 separated by commas or spaces.  You can qualify the macro argument to
 indicate whether all invocations must specify a non-blank value (through
@@ -6385,29 +6380,6 @@ adjacent string literals - even if separated only by a blank - will not be
 concatenated when determining macro arguments, even if they're only separated
 by white space.  This is unlike certain other pseudo ops, e.g. @code{.ascii}.
 
-Nested macros can access the arguments of their parents.  But also if their
-argument names clash with those of their parents, their versions are used.  So
-for example:
-
-@smallexample
-.macro OUTER arg1, arg2, arg3:vararg
-     .macro INNER arg4 arg2
-        .dc.a \arg2
-       .dc.a \arg3
-     .endm
-     INNER \arg1 bert
-       .dc.a \arg2
-.endm
-
-OUTER fred, jim, harry\arg4
-@end smallexample
-
-This will generate references to symbols called @samp{jim} - from the
-definition of the OUTER macro, @samp{bert} - from the definition in INNER
-where arg2 has been overridden and @samp{harryfred} - from the definition in
-INNER where the value of arg3 from OUTER is used, but with the value of arg4
-substituted into the symbol.
-
 @item .endm
 @cindex @code{endm} directive
 Mark the end of a macro definition.
@@ -6423,33 +6395,6 @@ Exit early from the current macro definition.
 executed in this pseudo-variable; you can copy that number to your
 output with @samp{\@@}, but @emph{only within a macro definition}.
 
-Note - the @samp{\@@} counter is incremented at the end of the expansion of a
-macro, but before the contents of any nested macros are evaluated.  This can
-lead to counter-intuitive behaviour when nested macros are used.  For example:
-
-@smallexample
-  .macro o
-    .macro i
-    _i\@@_:
-    .endm
-    i
-    _o\@@_:
-  .endm
-  o
-@end smallexample
-
-Produces two symbols @samp{_o0_} and @samp{_i1_}.  This happens because the
-@samp{o} macro executes entirely first, putting the definition and invocation
-of the @samp{i} macro into the input buffer.  It also puts the definition of
-the @samp{_o\@@_} symbol into the input buffer, evaluating the @samp{\@@}
-counter in the process and so generating a symbol called @samp{_o0_}.
-
-That finishes the invocation of @samp{o} so the @samp{\@@} counter is
-incremented.  Then the input buffer is re-evaluated and the definition and
-invocation of macro @samp{i} is found.  This results in @samp{_i\@@_} being put
-into the input buffer and this time @samp{\@@} evaluates to 1, so the symbol
-created is @samp{_i1_}.
-
 @cindex number of times a macro has been executed
 @cindex macro, execution count
 @item \+
@@ -6736,9 +6681,6 @@ those explicitly specified with @code{.eject}.
 Undefine the macro @var{name}, so that later uses of the string will not be
 expanded.  @xref{Macro}.
 
-Note - nested macros are automatically purged at the end of the macro that
-defines them.
-
 @ifset ELF
 @node PushSection
 @section @code{.pushsection @var{name} [, @var{subsection}] [, "@var{flags}"[, @@@var{type}[,@var{arguments}]]]}
index 3433bc6472d640c731e8ef97e291c35c9a50593a..2e0ce832b2bc01699680ff15f0d553140c82303a 100644 (file)
@@ -23,7 +23,6 @@
 #include "input-file.h"
 #include "sb.h"
 #include "listing.h"
-#include "macro.h"
 
 /*
  * O/S independent module to supply buffers of sanitised source code
@@ -291,13 +290,12 @@ input_scrub_include_sb (sb *from, char *position, enum expansion expansion)
       ++macro_nest;
     }
 
+#ifdef md_macro_start
   if (expansion == expanding_macro)
     {
-#ifdef md_macro_start
       md_macro_start ();
-#endif
-      increment_macro_nesting_depth ();
     }
+#endif
 
   next_saved_file = input_scrub_push (position);
 
@@ -352,7 +350,6 @@ input_scrub_next_buffer (char **bufp)
                 data.  */
              md_macro_end ();
 #endif
-             decrement_macro_nesting_depth ();
            }
          if (from_sb_expansion != expanding_app)
            --macro_nest;
index 9eefc8360b11fb1c87011f2d7aaab2edd6893729..5ae76c6e661b0e69552886f7f657c27653fc87a4 100644 (file)
 
 /* The macro hash table.  */
 
-/* Macro nesting depth.  Similar to macro_nest defined in sb.c, but this
-   counter is specific to macros, whereas macro_nest also counts repeated
-   string blocks.  */
-static unsigned int macro_nesting_depth;
+htab_t macro_hash;
 
-/* Maximum nesting depth.  Ideally the same as the value of max_macro_nest
-   as defined in as.c (ie 100).  But there is one test in the assembler
-   testsuite (bfin/allinsn16.s) that nests macros to a depth of 8192.  So
-   we have a ridiculously large number here.  */
-#define MAX_MACRO_DEPTH 8193
+/* Whether any macros have been defined.  */
 
-static htab_t macro_hash[MAX_MACRO_DEPTH];
-
-/* Whether any macros have been defined.
-   FIXME:  This could be a counter that is incremented
-   with .macro and decremented with .purgem.  */
-
-static bool macros_defined = false;
+int macro_defined;
 
 /* Whether we should strip '@' characters.  */
 
@@ -73,18 +60,6 @@ static unsigned int macro_number;
 
 static void free_macro (macro_entry *);
 
-bool
-add_macro (macro_entry * macro, bool replace)
-{
-  if (str_hash_insert (macro_hash [macro_nesting_depth],
-                      macro->name, macro, replace) == NULL)
-    {
-      macros_defined = true;
-      return true;
-    }
-  return false;
-}
-
 static void
 macro_del_f (void *ent)
 {
@@ -97,23 +72,15 @@ macro_del_f (void *ent)
 void
 macro_init (void)
 {
-  int i;
-
-  for (i = 0; i < MAX_MACRO_DEPTH; i++)
-    macro_hash[i] = htab_create_alloc (16, hash_string_tuple, eq_string_tuple,
-                                      macro_del_f, notes_calloc, NULL);
-  macros_defined = false;
+  macro_hash = htab_create_alloc (16, hash_string_tuple, eq_string_tuple,
+                                 macro_del_f, notes_calloc, NULL);
+  macro_defined = 0;
 }
 
 void
 macro_end (void)
 {
-  int i;
-
-  for (i = MAX_MACRO_DEPTH; i--;)
-    htab_delete (macro_hash[i]);
-
-  macros_defined = false;
+  htab_delete (macro_hash);
 }
 
 /* Read input lines till we get to a TO string.
@@ -688,13 +655,6 @@ free_macro (macro_entry *macro)
   free (macro);
 }
 
-static macro_entry * last_recorded_macro = NULL;
-void
-macro_record_invocation (macro_entry * macro)
-{
-  last_recorded_macro = macro;
-}
-
 /* Define a new macro.  */
 
 macro_entry *
@@ -758,19 +718,15 @@ define_macro (sb *in, sb *label, size_t (*get_line) (sb *))
   /* And stick it in the macro hash table.  */
   for (idx = 0; idx < name.len; idx++)
     name.ptr[idx] = TOLOWER (name.ptr[idx]);
-
-  if (macro_nesting_depth > 0)
-    macro->parent = last_recorded_macro;
-  else
-    macro->parent = NULL;
-
   if (!error)
     {
-      if (! add_macro (macro, false))
+      if (str_hash_insert (macro_hash, macro->name, macro, 0) != NULL)
        error = _("Macro `%s' was already defined");
     }
 
-  if (error != NULL)
+  if (!error)
+    macro_defined = 1;
+  else
     {
       as_bad_where (macro->file, macro->line, error, macro->name);
       free_macro (macro);
@@ -794,25 +750,11 @@ get_apost_token (size_t idx, sb *in, sb *name, int kind)
   return idx;
 }
 
-static const char *
-macro_expand_body (sb *, sb *, formal_entry *, struct htab *,
-                  const macro_entry *, unsigned int);
-
-/* Find the actual value for a formal parameter starting at START inside IN.
-    Appends the value of parameter onto OUT.
-   The hash table of formal parameters is provided by FORMAL_HASH.
-   The character that indicated the presense of a formal parameter is passed
-    in KIND.
-   If COPYIFNOTTHERE is true and the parameter is not found in the hash table
-    then it is appended as plain text onto OUT.
-   The macro containing the formal parameters is passed in MACRO.
-    This can be empty.
-   Returns the offset inside IN after advanceing past the parameter.
-   Also stores the parameter's name into T.  */
+/* Substitute the actual value for a formal parameter.  */
 
 static size_t
 sub_actual (size_t start, sb *in, sb *t, struct htab *formal_hash,
-           int kind, sb *out, int copyifnotthere, const macro_entry * macro)
+           int kind, sb *out, int copyifnotthere)
 {
   size_t src;
   formal_entry *ptr;
@@ -826,12 +768,16 @@ sub_actual (size_t start, sb *in, sb *t, struct htab *formal_hash,
     ptr = NULL;
   else
     ptr = str_hash_find (formal_hash, sb_terminate (t));
-  
   if (ptr)
     {
-      sb * add = ptr->actual.len ? &ptr->actual : &ptr->def;
-
-      sb_add_sb (out, add);
+      if (ptr->actual.len)
+       {
+         sb_add_sb (out, &ptr->actual);
+       }
+      else
+       {
+         sb_add_sb (out, &ptr->def);
+       }
     }
   else if (kind == '&')
     {
@@ -845,56 +791,6 @@ sub_actual (size_t start, sb *in, sb *t, struct htab *formal_hash,
     {
       sb_add_sb (out, t);
     }
-  else if (!macro_strip_at
-          && macro_nesting_depth > 0
-          && macro != NULL
-          && macro->parent != NULL)
-    {
-      const macro_entry * orig_macro = macro;
-      bool success = false;
-
-      /* We have failed to find T, but we are inside nested macros.  So check
-        the parent macros so see if they have a FORMAL that matches T.  */
-      while (macro->parent != NULL)
-       {
-         macro = macro->parent;
-
-         ptr = str_hash_find (macro->formal_hash, t->ptr);
-         if (ptr == NULL)
-           continue;
-
-         sb * add = ptr->actual.len ? &ptr->actual : &ptr->def;
-
-         /* The parent's FORMALs might contain parameters that need further
-            substitution.  See gas/testsuite/gas/arm/macro-vld1.s for an
-            example of this.  */
-         if (memchr (add->ptr, '\\', add->len))
-           {
-             sb newadd;
-
-             sb_new (&newadd);
-             /* FIXME: Should we do something if the call to
-                macro_expand_body returns an error message ?  */
-             (void) macro_expand_body (add, &newadd, NULL, NULL,
-                                       orig_macro, orig_macro->count);
-             sb_add_sb (out, &newadd);
-             sb_kill (&newadd);
-           }
-         else
-           {
-             sb_add_sb (out, add);
-           }
-         success = true;
-         break;
-       }
-      if (! success)
-       {
-         /* We reached the outermost macro and failed to find T, so
-            just copy the entire parameter as is.  */
-         sb_add_char (out, '\\');
-         sb_add_sb (out, t);
-       }
-    }
   else
     {
       sb_add_char (out, '\\');
@@ -903,12 +799,7 @@ sub_actual (size_t start, sb *in, sb *t, struct htab *formal_hash,
   return src;
 }
 
-/* Expands the body of a macro / block of text IN, copying it into OUT.
-   Parameters for substitution are found in FORMALS and FORMAL_HASH or
-   MACRO.
-   The number of times that this macro / block of text have already been
-   copied into the output is held in INSTANCE.
-   Returns NULL upon success or an error message otherwise.  */
+/* Expand the body of a macro.  */
 
 static const char *
 macro_expand_body (sb *in, sb *out, formal_entry *formals,
@@ -920,38 +811,18 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals,
   int inquote = 0, macro_line = 0;
   formal_entry *loclist = NULL;
   const char *err = NULL;
-  int nesting = 0;
 
-  if (formals == NULL && macro != NULL)
-    formals = macro->formals;
-
-  if (formal_hash == NULL && macro != NULL)
-    formal_hash = macro->formal_hash;
-  
   sb_new (&t);
 
   while (src < in->len && !err)
     {
-      if (in->ptr[src] == '.')
-       {
-         /* Check to see if we have encountered ".macro" or ".endm" */
-         if (in->len > src + 5
-             && strncmp (in->ptr + src, ".macro", 6) == 0)
-           ++ nesting;
-
-         else if (in->len > src + 4
-                  && strncmp (in->ptr + src, ".endm", 5) == 0)
-           -- nesting;
-       }
-
       if (in->ptr[src] == '&')
        {
          sb_reset (&t);
          if (flag_mri)
            {
              if (src + 1 < in->len && in->ptr[src + 1] == '&')
-               src = sub_actual (src + 2, in, &t, formal_hash,
-                                 '\'', out, 1, macro);
+               src = sub_actual (src + 2, in, &t, formal_hash, '\'', out, 1);
              else
                sb_add_char (out, in->ptr[src++]);
            }
@@ -959,8 +830,7 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals,
            {
              /* Permit macro parameter substitution delineated with
                 an '&' prefix and optional '&' suffix.  */
-             src = sub_actual (src + 1, in, &t, formal_hash,
-                               '&', out, 0, macro);
+             src = sub_actual (src + 1, in, &t, formal_hash, '&', out, 0);
            }
        }
       else if (in->ptr[src] == '\\')
@@ -981,12 +851,7 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals,
              else
                as_bad_where (macro->file, macro->line + macro_line, _("missing `)'"));
            }
-         else if (src < in->len
-                  && in->ptr[src] == '@'
-                  /* PR 32391: Do not perform the substition inside nested
-                     macros.  Instead wait until they are re-evaluated and
-                     perform the substition then.  */
-                  && ! nesting)
+         else if (src < in->len && in->ptr[src] == '@')
            {
              /* Sub in the total macro invocation number.  */
 
@@ -995,12 +860,7 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals,
              sprintf (buffer, "%u", macro_number);
              sb_add_string (out, buffer);
            }
-         else if (src < in->len
-                  && in->ptr[src] == '+'
-                  /* PR 32391: Do not perform the substition inside nested
-                     macros.  Instead wait until they are re-evaluated and
-                     perform the substition then.  */
-                  && ! nesting)
+         else if (src < in->len && in->ptr[src] == '+')
            {
              /* Sub in the current macro invocation number.  */
 
@@ -1044,18 +904,7 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals,
          else
            {
              sb_reset (&t);
-
-             if (nesting)
-               {
-                 src = get_apost_token (src, in, &t, '\'');
-                 sb_add_char (out, '\\');
-                 sb_add_sb (out, &t);
-               }
-             else
-               {
-                 src = sub_actual (src, in, &t, formal_hash,
-                                   '\'', out, 0, macro);
-               }
+             src = sub_actual (src, in, &t, formal_hash, '\'', out, 0);
            }
        }
       else if ((flag_macro_alternate || flag_mri)
@@ -1074,7 +923,7 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals,
              sb_reset (&t);
              src = sub_actual (src, in, &t, formal_hash,
                                (macro_strip_at && inquote) ? '@' : '\'',
-                               out, 1, macro);
+                               out, 1);
            }
          else
            {
@@ -1186,7 +1035,6 @@ macro_expand_body (sb *in, sb *out, formal_entry *formals,
 
   if (!err && (out->len == 0 || out->ptr[out->len - 1] != '\n'))
     sb_add_char (out, '\n');
-
   return err;
 }
 
@@ -1371,7 +1219,8 @@ macro_expand (size_t idx, sb *in, macro_entry *m, sb *out)
            }
        }
 
-      err = macro_expand_body (&m->sub, out, NULL, NULL, m, m->count);
+      err = macro_expand_body (&m->sub, out, m->formals, m->formal_hash, m,
+                              m->count);
     }
 
   /* Discard any unnamed formal arguments.  */
@@ -1404,22 +1253,20 @@ macro_expand (size_t idx, sb *in, macro_entry *m, sb *out)
 }
 
 /* Check for a macro.  If one is found, put the expansion into
-   *EXPAND.  Return TRUE if a macro is found, FALSE otherwise.  */
+   *EXPAND.  Return 1 if a macro is found, 0 otherwise.  */
 
-bool
+int
 check_macro (const char *line, sb *expand,
             const char **error, macro_entry **info)
 {
   const char *s;
   char *copy, *cls;
+  macro_entry *macro;
   sb line_sb;
 
-  if (! macros_defined)
-    return false;
-
   if (! is_name_beginner (*line)
       && (! flag_mri || *line != '.'))
-    return false;
+    return 0;
 
   s = line + 1;
   while (is_part_of_name (*s))
@@ -1431,17 +1278,11 @@ check_macro (const char *line, sb *expand,
   for (cls = copy; *cls != '\0'; cls ++)
     *cls = TOLOWER (*cls);
 
-  macro_entry *macro = NULL;
-  for (int i = macro_nesting_depth; i >= 0; i--)
-    {
-      macro = str_hash_find (macro_hash[i], copy);
-      if (macro != NULL)
-       break;
-    }
+  macro = str_hash_find (macro_hash, copy);
   free (copy);
 
   if (macro == NULL)
-    return false;
+    return 0;
 
   /* Wrap the line up in an sb.  */
   sb_new (&line_sb);
@@ -1457,7 +1298,7 @@ check_macro (const char *line, sb *expand,
   if (info)
     *info = macro;
 
-  return true;
+  return 1;
 }
 
 /* Delete a macro.  */
@@ -1475,20 +1316,11 @@ delete_macro (const char *name)
     copy[i] = TOLOWER (name[i]);
   copy[i] = '\0';
 
-  int j;
-  for (j = macro_nesting_depth; j >= 0; j--)
-    {
-      macro = str_hash_find (macro_hash [j], copy);
-      if (macro != NULL)
-       {
-         str_hash_delete (macro_hash[j], copy);
-         break;
-       }
-    }
-
-  if (j < 0)
+  macro = str_hash_find (macro_hash, copy);
+  if (macro != NULL)
+    str_hash_delete (macro_hash, copy);
+  else
     as_warn (_("Attempt to purge non-existing macro `%s'"), copy);
-
   free (copy);
 }
 
@@ -1590,25 +1422,3 @@ expand_irp (int irpc, size_t idx, sb *in, sb *out, size_t (*get_line) (sb *))
 
   return err;
 }
-
-void
-increment_macro_nesting_depth (void)
-{
- if (macro_nesting_depth >= (MAX_MACRO_DEPTH - 1))
-    as_fatal (_("macros nested too deeply"));
-  else
-    ++macro_nesting_depth;
-}
-
-void
-decrement_macro_nesting_depth (void)
-{
-  if (macro_nesting_depth == 0)
-    as_fatal (_("too much macro un-nesting"));
-  else
-    {
-      /* FIXME: Potential memory leak here.  */
-      htab_empty (macro_hash [macro_nesting_depth]);
-      --macro_nesting_depth;
-    }
-}
index 55b28b2f82a94b6f41b5896449f545b42ec4278c..3ebcfe8c8fddc319791ef064dd51b11c97ba6e63 100644 (file)
@@ -64,28 +64,31 @@ typedef struct macro_struct
   int             formal_count;                /* Number of formal args.  */
   formal_entry *  formals;             /* List of formal_structs.  */
   htab_t          formal_hash;         /* Hash table of formals.  */
-  struct macro_struct * parent;         /* Parent of nested macros.  */
   const char *    name;                        /* Macro name.  */
   const char *    file;                        /* File the macro was defined in.  */
   unsigned int    line;                        /* Line number of definition.  */
   unsigned int    count;                /* Invocation count.  */
 } macro_entry;
 
-/* The macro/text block nesting level.  */
+/* Whether any macros have been defined.  */
+
+extern int macro_defined;
+
+/* The macro nesting level.  */
 
 extern int macro_nest;
 
+/* The macro hash table.  */
+
+extern htab_t macro_hash;
+
 extern int buffer_and_nest (const char *, const char *, sb *,
                            size_t (*) (sb *));
 extern void macro_init (void);
 extern void macro_end (void);
 extern macro_entry *define_macro (sb *, sb *, size_t (*) (sb *));
-extern bool check_macro (const char *, sb *, const char **, macro_entry **);
+extern int check_macro (const char *, sb *, const char **, macro_entry **);
 extern void delete_macro (const char *);
 extern const char *expand_irp (int, size_t, sb *, sb *, size_t (*) (sb *));
-extern void increment_macro_nesting_depth (void);
-extern void decrement_macro_nesting_depth (void);
-extern void macro_record_invocation (macro_entry *);
-extern bool add_macro (macro_entry *, bool);
 
 #endif
index 5be2686822d6f1556d0ff8dd9b9a4a782d071357..6d0d4b5e31a18a81ec47f6599fef0f1fa6ee4798 100644 (file)
@@ -656,8 +656,7 @@ poend (void)
     }
 
 /* Helper function of read_a_source_file, which tries to expand a macro.  */
-
-static bool
+static int
 try_macro (char term, const char *line)
 {
   sb out;
@@ -674,14 +673,12 @@ try_macro (char term, const char *line)
       sb_kill (&out);
       buffer_limit =
        input_scrub_next_buffer (&input_line_pointer);
-
-      macro_record_invocation (macro);
 #ifdef md_macro_info
       md_macro_info (macro);
 #endif
-      return true;
+      return 1;
     }
-  return false;
+  return 0;
 }
 
 #ifdef HANDLE_BUNDLE
@@ -1273,7 +1270,7 @@ read_a_source_file (const char *name)
                          s_ignore (0);
                          nul_char = next_char = *--input_line_pointer;
                          *input_line_pointer = '\0';
-                         if (! try_macro (next_char, s))
+                         if (! macro_defined || ! try_macro (next_char, s))
                            {
                              *end = '\0';
                              as_bad (_("unknown pseudo-op: `%s'"), s);
@@ -1310,7 +1307,7 @@ read_a_source_file (const char *name)
 
                      generate_lineno_debug ();
 
-                     if (try_macro (next_char, s))
+                     if (macro_defined && try_macro (next_char, s))
                        continue;
 
                      if (mri_pending_align)
@@ -2820,7 +2817,7 @@ s_macro (int ignore ATTRIBUTE_UNUSED)
          as_warn_where (macro->file, macro->line,
                         _("attempt to redefine pseudo-op `%s' ignored"),
                         macro->name);
-         delete_macro (macro->name);
+         str_hash_delete (macro_hash, macro->name);
        }
     }
 
index de3df4d803da2476aaee5c71a640784dd89cda84..359330932ad4ad0cbff6c45eb971459b081dfba1 100644 (file)
@@ -112,4 +112,6 @@ run_list_test count
 run_list_test irp-count
 run_list_test irpc-quote
 run_list_test rept-count
-run_dump_test nesting
+run_dump_test nesting1
+run_dump_test nesting2
+run_dump_test nesting3
diff --git a/gas/testsuite/gas/macros/nesting.d b/gas/testsuite/gas/macros/nesting.d
deleted file mode 100644 (file)
index 2f44aed..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#nm: -j 
-#name: Nested macros (PR 32391)
-# Sone targets do not support macros used like this.
-#skip: tic*-*-* mmix-*
-
-#...
-_m7_
-_m8_
-after_at_0
-after_at_3
-after_plus_0
-after_plus_1
-before_at_0
-before_at_3
-before_plus_0
-before_plus_1
-bert
-harryfred
-i3_bar
-inside_at_1
-inside_at_2
-inside_at_4
-inside_at_5
-inside_plus_0
-inside_plus_1
-jim
-o3_foo
-other_inner_6
diff --git a/gas/testsuite/gas/macros/nesting.s b/gas/testsuite/gas/macros/nesting.s
deleted file mode 100644 (file)
index 9746ca1..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
- .text
-/* PR 32391: Automatic counters inside macros should increment when nested
-   macros finish execution.  */
- .macro o1
- .global before_at_\@
-before_at_\@:
- .global before_plus_\+
-before_plus_\+:
-
- .macro i1
- .global inside_at_\@
-inside_at_\@:
- .global inside_plus_\+
-inside_plus_\+:
- .endm
-
- i1
- i1
-
- .global after_at_\@
-after_at_\@:
- .global after_plus_\+
-after_plus_\+:
-
- .endm
-
-/* Invoking o1 should produce these symbols in this order:
-
-   before_at_0
-   before_plus_0
-   inside_at_1
-   inside_plus_0
-   inside_at_2
-   inside_plus_1
-   after_at_0
-   after_plus_0  */
- o1
-
-/* A second invocation of o1 should not produce any errors about
-   symbols or macros being redefined.  */
- o1
-
-/* This definition should not collide with the definition inside o1.  */
- .macro i1
- .global other_inner_\@
-other_inner_\@:
- .endm
-
-/* And invoking it should invoke the second defintion of i1, not the first.  */
- i1
-
- .macro o2
- .global _m\@_
-_m\@_:
- .macro i2
- .global _m\@_
-_m\@_:
- .endm
- i2
- .endm
-
-/* This should not generate conflicting symbols because the assembler
-   inserts the contents of o2 into the input buffer as pure text (ie
-   without evaluating i2).  The first use of \@ is evaluated at this
-   time, creating _m4_.  But the second use is not evaluated because
-   it is inside a .macro definition.
-
-   This finishes the evaluation of o2, so the \@ counter is incremented.
-
-   Next the input buffer is re-evaluated and the i2 macro definition
-   and invocation are encounterd.  The text from i2 are inserted into
-   the input buffer and at this point the second use of \@ is evaluated
-   resulting in the creation of a symbol called _m5_.  */
- o2
-
-/* Macro arguments should be independent of nesting.  */
- .macro O3 arg
- .global o3_\arg
-o3_\arg:
-
- .macro I3 arg
- .global i3_\arg
-i3_\arg:
- .endm
-
- i3 bar                /* Macro names are case insensitive.  */
- .endm
-
- o3 foo                /* Should produce two labels: o3_foo and i3_bar.  */
-
-/* Nested macros can access the arguments of their parents.
-   In addition their arguments can be substituted into the arguments
-   that are substited from their parents:  */
- .macro OUTER arg1, arg2, arg3:vararg
- .macro INNER arg4 arg2
-        .dc.a \arg2
- .dc.a \arg3
- .endm
- INNER \arg1 bert
- .dc.a \arg2
- .endm
-
-/* This produces references to "jim", "bert" and "harryfred".  */
- OUTER fred, jim, harry\arg4
diff --git a/gas/testsuite/gas/macros/nesting1.d b/gas/testsuite/gas/macros/nesting1.d
new file mode 100644 (file)
index 0000000..10a90ab
--- /dev/null
@@ -0,0 +1,7 @@
+#nm: -j
+#name: Nested macros (PR 32484)
+# Sone targets do not support macros used like this.
+#skip: mmix-*
+
+#...
+foo
diff --git a/gas/testsuite/gas/macros/nesting1.s b/gas/testsuite/gas/macros/nesting1.s
new file mode 100644 (file)
index 0000000..3d415e1
--- /dev/null
@@ -0,0 +1,14 @@
+       .text
+.macro entry fname
+\fname:
+.endm
+
+.macro func fname, t
+ entry \fname
+ .macro data
+  .dc.\()\t 0
+ .endm
+ data
+.endm
+
+func foo, a
diff --git a/gas/testsuite/gas/macros/nesting2.d b/gas/testsuite/gas/macros/nesting2.d
new file mode 100644 (file)
index 0000000..88649b1
--- /dev/null
@@ -0,0 +1,7 @@
+#nm: -j
+#name: Nested macros (PR 32486)
+# Sone targets do not support macros used like this.
+#skip: mmix-*
+
+#...
+foo
diff --git a/gas/testsuite/gas/macros/nesting2.s b/gas/testsuite/gas/macros/nesting2.s
new file mode 100644 (file)
index 0000000..ff8a7f4
--- /dev/null
@@ -0,0 +1,10 @@
+.macro function name
+ .macro endfunc
+ .endm
+       .text
+\name:
+.endm
+
+function foo
+       .dc.a 0
+endfunc
diff --git a/gas/testsuite/gas/macros/nesting3.d b/gas/testsuite/gas/macros/nesting3.d
new file mode 100644 (file)
index 0000000..2621957
--- /dev/null
@@ -0,0 +1,7 @@
+#nm: -j
+#name: Nested macros (PR 32487)
+# Sone targets do not support macros used like this.
+#skip: mmix-*
+
+#...
+foo
diff --git a/gas/testsuite/gas/macros/nesting3.s b/gas/testsuite/gas/macros/nesting3.s
new file mode 100644 (file)
index 0000000..4488009
--- /dev/null
@@ -0,0 +1,13 @@
+       .text
+.macro func
+       foo
+.endm
+
+.macro do_foo
+.macro foo
+foo:
+       .dc.a 0
+.endm
+.endm
+do_foo
+func