[PATCH] gas: Revert PR 32391 related commits to fix 3 regressions

H.J. Lu hjl.tools@gmail.com
Thu Dec 26 08:12:36 GMT 2024


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.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
---
 gas/config/tc-iq2000.c              |   6 +-
 gas/doc/as.texi                     |  60 +-----
 gas/input-scrub.c                   |   7 +-
 gas/macro.c                         | 271 +++++-----------------------
 gas/macro.h                         |  17 +-
 gas/read.c                          |  15 +-
 gas/testsuite/gas/macros/macros.exp |   4 +-
 gas/testsuite/gas/macros/nesting.d  |  28 ---
 gas/testsuite/gas/macros/nesting.s  | 104 -----------
 gas/testsuite/gas/macros/nesting1.d |   7 +
 gas/testsuite/gas/macros/nesting1.s |  14 ++
 gas/testsuite/gas/macros/nesting2.d |   7 +
 gas/testsuite/gas/macros/nesting2.s |  10 +
 gas/testsuite/gas/macros/nesting3.d |   7 +
 gas/testsuite/gas/macros/nesting3.s |  13 ++
 15 files changed, 126 insertions(+), 444 deletions(-)
 delete mode 100644 gas/testsuite/gas/macros/nesting.d
 delete mode 100644 gas/testsuite/gas/macros/nesting.s
 create mode 100644 gas/testsuite/gas/macros/nesting1.d
 create mode 100644 gas/testsuite/gas/macros/nesting1.s
 create mode 100644 gas/testsuite/gas/macros/nesting2.d
 create mode 100644 gas/testsuite/gas/macros/nesting2.s
 create mode 100644 gas/testsuite/gas/macros/nesting3.d
 create mode 100644 gas/testsuite/gas/macros/nesting3.s

diff --git a/gas/config/tc-iq2000.c b/gas/config/tc-iq2000.c
index 1cbc578281f..2198ffda2b9 100644
--- a/gas/config/tc-iq2000.c
+++ b/gas/config/tc-iq2000.c
@@ -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;
 
 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
diff --git a/gas/doc/as.texi b/gas/doc/as.texi
index 1683594a0bb..6be54b57599 100644
--- a/gas/doc/as.texi
+++ b/gas/doc/as.texi
@@ -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}]]]}
diff --git a/gas/input-scrub.c b/gas/input-scrub.c
index 25fac879a56..878edc8fd36 100644
--- a/gas/input-scrub.c
+++ b/gas/input-scrub.c
@@ -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;
diff --git a/gas/macro.c b/gas/macro.c
index ded0645be8d..8b376f7f490 100644
--- a/gas/macro.c
+++ b/gas/macro.c
@@ -44,24 +44,11 @@
 
 /* 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,55 +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);
-	    }
-	  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, '\\');
@@ -902,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,
@@ -919,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++]);
 	    }
@@ -958,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] == '\\')
@@ -980,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.  */
 
@@ -994,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.  */
 
@@ -1043,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)
@@ -1073,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
 	    {
@@ -1185,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;
 }
 
@@ -1370,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.  */
@@ -1403,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))
@@ -1430,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);
@@ -1456,7 +1298,7 @@ check_macro (const char *line, sb *expand,
   if (info)
     *info = macro;
 
-  return true;
+  return 1;
 }
 
 /* Delete a macro.  */
@@ -1474,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);
 }
 
@@ -1589,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;
-    }
-}
diff --git a/gas/macro.h b/gas/macro.h
index 97f2a5a4066..e87f64e70ca 100644
--- a/gas/macro.h
+++ b/gas/macro.h
@@ -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
diff --git a/gas/read.c b/gas/read.c
index e5185f4ba26..589c7b080c2 100644
--- a/gas/read.c
+++ b/gas/read.c
@@ -655,8 +655,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;
@@ -673,14 +672,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
@@ -1272,7 +1269,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);
@@ -1309,7 +1306,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)
@@ -2819,7 +2816,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);
 	}
     }
 
diff --git a/gas/testsuite/gas/macros/macros.exp b/gas/testsuite/gas/macros/macros.exp
index 94ac37cdb8b..3a99f201749 100644
--- a/gas/testsuite/gas/macros/macros.exp
+++ b/gas/testsuite/gas/macros/macros.exp
@@ -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
index 2f44aedb2dc..00000000000
--- a/gas/testsuite/gas/macros/nesting.d
+++ /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
index 9746ca183ef..00000000000
--- a/gas/testsuite/gas/macros/nesting.s
+++ /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
index 00000000000..10a90ab8112
--- /dev/null
+++ b/gas/testsuite/gas/macros/nesting1.d
@@ -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
index 00000000000..3d415e1ef62
--- /dev/null
+++ b/gas/testsuite/gas/macros/nesting1.s
@@ -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
index 00000000000..88649b1402f
--- /dev/null
+++ b/gas/testsuite/gas/macros/nesting2.d
@@ -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
index 00000000000..ff8a7f4f75a
--- /dev/null
+++ b/gas/testsuite/gas/macros/nesting2.s
@@ -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
index 00000000000..26219571b9d
--- /dev/null
+++ b/gas/testsuite/gas/macros/nesting3.d
@@ -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
index 00000000000..4488009dd5f
--- /dev/null
+++ b/gas/testsuite/gas/macros/nesting3.s
@@ -0,0 +1,13 @@
+	.text
+.macro func
+	foo
+.endm
+
+.macro do_foo
+.macro foo
+foo:
+	.dc.a 0
+.endm
+.endm
+do_foo
+func
-- 
2.47.1



More information about the Binutils mailing list