[RFA:] Fix bug with #APP/#NO_APP when using macros.

Hans-Peter Nilsson hans-peter.nilsson@axis.com
Thu May 8 08:08:00 GMT 2003


The app4 test is the one closest to the original case, while the
others caught other bugs I made and stirred up during fixing.
Since the tests are all small and test a few corner cases, I
thought best to include them all.

Regarding the read.c patch, note that new_tmp isn't used after
the break, so old "new_tmp += size;" was dead code.  Not only
was the old_* kludge I replaced nauseating, it was also buggy;
it couldn't handle the input feed changing with the usual
mechanisms (now also used as per the patch), as when expanding a
macro.  The change is minimal in that I didn't rewrite the whole
#APP expansion thing (with its use of temporary strings), I just
made the #APP expansion go finally into a string buffer as used
elsewhere.

In response to the comment in the #APP processing ("The end of
the #APP wasn't in this buffer.  We keep reading in buffers
until we find the #NO_APP that goes with this #APP.  There is
one.  The specs guarentee it..." (sic)): There is no "spec" for
#APP/#NO_APP, AFAIK.  In particular, there is no guarantee that
there's ever a #NO_APP for every #APP.  Actually, no gcc port
defines ASM_FILE_END to emit #NO_APP, AFAICT, so most often
there is no last #NO_APP for the last asm in file scope.  Or
perhaps the missing last #NO_APP is a generic gcc bug.
Anyhoo...  As seen with the test app2, even if there's a
matching #NO_APP, things go wrong.

An alternative is to remove this support completely and ignore
#NO_APP/#APP; always scrub.  This is IMHO reasonable, since
apparently no other GCC port uses this feature.

Who is this JF, and why wasn't the nice string buffer functions
that SAC wrote used?  Or do I mix up the timeline?  (Reply in
private, if so inclined.)

End of rant.

Tested on cris-axis-elf, i686-pc-linux-gnu and
mmix-knuth-mmixware (where I see that lots of mmo ld tests are
broken, film at 11), no regressions from this patch.  The patch
fixes the test-cases on these targets.

Ok to commit?

gas/testsuite:
	* gas/macros/app1.s, gas/macros/app1.d, gas/macros/app2.s,
	gas/macros/app2.d, gas/macros/app3.s, gas/macros/app3.d,
	gas/macros/app4.s, gas/macros/app4b.s, gas/macros/app4.d: New
	tests.
	* gas/macros/macros.exp: Run them.

gas:
	* read.c (old_buffer, old_input, old_limit): Remove variables.
 	(read_a_source_file): Delete label contin.
	<handling #APP/#NO_APP>: Use an "sb" to push #APP expansion into
	input as with macros, instead of in separate old_* variables.
	Zero-terminate string being scrubbed.

--- /dev/null	Tue Oct 29 15:57:07 2002
+++ app1.d	Thu May  8 08:22:16 2003
@@ -0,0 +1,4 @@
+#nm: -n
+#name: APP with macro without NO_APP
+0+ t a
+0+[1-f] t b
--- /dev/null	Tue Oct 29 15:57:07 2002
+++ app1.s	Wed May  7 18:22:42 2003
@@ -0,0 +1,10 @@
+#NO_APP
+ .text
+ .macro foo
+a:
+ .long 42
+ .endm
+#APP
+ foo
+b:
+ .long 56
--- /dev/null	Tue Oct 29 15:57:07 2002
+++ app2.d	Thu May  8 08:21:41 2003
@@ -0,0 +1,4 @@
+#nm: -n
+#name: APP with macro then NO_APP
+0+ t a
+0+[1-f] t b
--- /dev/null	Tue Oct 29 15:57:07 2002
+++ app2.s	Thu May  8 06:21:39 2003
@@ -0,0 +1,11 @@
+#NO_APP
+ .text
+ .macro foo
+a:
+ .long 42
+ .endm
+#APP
+ foo
+b:
+ .long 56
+#NO_APP
--- /dev/null	Tue Oct 29 15:57:07 2002
+++ app3.d	Thu May  8 08:22:58 2003
@@ -0,0 +1,5 @@
+#nm: -n
+#name: APP with macro then NO_APP then more code
+0+ t a
+0+[1-f] t b
+0+[2-f] t c
--- /dev/null	Tue Oct 29 15:57:07 2002
+++ app3.s	Thu May  8 06:29:01 2003
@@ -0,0 +1,13 @@
+#NO_APP
+ .text
+ .macro foo
+a:
+ .long 42
+ .endm
+#APP
+ foo
+b:
+ .long 56
+#NO_APP
+c:
+ .long 78
--- /dev/null	Tue Oct 29 15:57:07 2002
+++ app4.d	Thu May  8 08:33:47 2003
@@ -0,0 +1,6 @@
+#as: -I$srcdir/$subdir
+#nm: -n
+#name: included file with .if 0 wrapped in APP/NO_APP, no final NO_APP, macro in main file
+0+ t d
+0+[1-f] t a
+0+[2-f] t b
--- /dev/null	Tue Oct 29 15:57:07 2002
+++ app4.s	Thu May  8 08:12:36 2003
@@ -0,0 +1,9 @@
+ .text
+ .macro foo
+a:
+ .long 42
+ .endm
+ .include "app4b.s"
+ foo
+b:
+ .long 56
--- /dev/null	Tue Oct 29 15:57:07 2002
+++ app4b.s	Thu May  8 08:32:21 2003
@@ -0,0 +1,10 @@
+#NO_APP
+d:
+ .long 21
+#APP
+ .if 0
+#NO_APP
+ .err
+x:
+#APP
+ .endif
Index: macros.exp
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/macros/macros.exp,v
retrieving revision 1.13
diff -c -p -r1.13 macros.exp
*** macros.exp	18 Nov 2002 08:28:40 -0000	1.13
--- macros.exp	8 May 2003 06:44:41 -0000
*************** if { ![istarget hppa*-*-*] || [istarget 
*** 40,42 ****
--- 40,47 ----
      setup_xfail "*c4x*-*-*" "*c54x*-*"
      run_dump_test strings
  }
+ 
+ run_dump_test app1
+ run_dump_test app2
+ run_dump_test app3
+ run_dump_test app4

Index: read.c
===================================================================
RCS file: /cvs/src/src/gas/read.c,v
retrieving revision 1.60
diff -c -p -r1.60 read.c
*** read.c	2 May 2003 02:41:45 -0000	1.60
--- read.c	8 May 2003 06:38:26 -0000
*************** static char *buffer_limit;	/*->1 + last 
*** 168,177 ****
     internals manual.  */
  int target_big_endian = TARGET_BYTES_BIG_ENDIAN;
  
- static char *old_buffer;	/* JF a hack.  */
- static char *old_input;
- static char *old_limit;
- 
  /* Variables for handling include file directory table.  */
  
  /* Table of pointers to directories to search for .include's.  */
--- 168,173 ----
*************** read_a_source_file (name)
*** 533,541 ****
    while ((buffer_limit = input_scrub_next_buffer (&input_line_pointer)) != 0)
      {				/* We have another line to parse.  */
        know (buffer_limit[-1] == '\n');	/* Must have a sentinel.  */
!     contin:			/* JF this goto is my fault I admit it.
! 				   Someone brave please re-write the whole
! 				   input section here?  Pleeze???  */
        while (input_line_pointer < buffer_limit)
  	{
  	  /* We have more of this buffer to parse.  */
--- 529,535 ----
    while ((buffer_limit = input_scrub_next_buffer (&input_line_pointer)) != 0)
      {				/* We have another line to parse.  */
        know (buffer_limit[-1] == '\n');	/* Must have a sentinel.  */
! 
        while (input_line_pointer < buffer_limit)
  	{
  	  /* We have more of this buffer to parse.  */
*************** read_a_source_file (name)
*** 953,958 ****
--- 947,953 ----
  
  	  if (c && strchr (line_comment_chars, c))
  	    {			/* Its a comment.  Better say APP or NO_APP.  */
+ 	      sb sbuf;
  	      char *ends;
  	      char *new_buf;
  	      char *new_tmp;
*************** read_a_source_file (name)
*** 965,970 ****
--- 960,966 ----
  		continue;	/* We ignore it */
  	      s += 4;
  
+ 	      sb_new (&sbuf);
  	      ends = strstr (s, "#NO_APP\n");
  
  	      if (!ends)
*************** read_a_source_file (name)
*** 1026,1032 ****
  
  		  if (size < space)
  		    {
! 		      new_tmp += size;
  		      break;
  		    }
  
--- 1022,1028 ----
  
  		  if (size < space)
  		    {
! 		      new_tmp[size] = 0;
  		      break;
  		    }
  
*************** read_a_source_file (name)
*** 1037,1049 ****
  
  	      if (tmp_buf)
  		free (tmp_buf);
- 	      old_buffer = buffer;
- 	      old_input = input_line_pointer;
- 	      old_limit = buffer_limit;
- 	      buffer = new_buf;
- 	      input_line_pointer = new_buf;
- 	      buffer_limit = new_tmp;
  
  	      continue;
  	    }
  
--- 1033,1051 ----
  
  	      if (tmp_buf)
  		free (tmp_buf);
  
+ 	      /* We've "scrubbed" input to the preferred format.  In the
+ 		 process we may have consumed the whole of the remaining
+ 		 file (and included files).  We handle this formatted
+ 		 input similar to that of macro expansion, letting
+ 		 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);
+ 	      input_scrub_include_sb (&sbuf, input_line_pointer, 0);
+ 	      sb_kill (&sbuf);
+ 	      buffer_limit = input_scrub_next_buffer (&input_line_pointer);
+ 	      free (new_buf);
  	      continue;
  	    }
  
*************** read_a_source_file (name)
*** 1061,1080 ****
  #ifdef md_after_pass_hook
        md_after_pass_hook ();
  #endif
- 
-       if (old_buffer)
- 	{
- 	  free (buffer);
- 	  bump_line_counters ();
- 	  if (old_input != 0)
- 	    {
- 	      buffer = old_buffer;
- 	      input_line_pointer = old_input;
- 	      buffer_limit = old_limit;
- 	      old_buffer = 0;
- 	      goto contin;
- 	    }
- 	}
      }
  
   quit:
--- 1063,1068 ----

brgds, H-P



More information about the Binutils mailing list