This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


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

cpplib bug fix (macro expansion)



This patch fixes a bug in an unusual case of macro expansion with
cpplib.

#define a(x) x bar
#define foo(y) junk
a(foo)

should become

foo bar

when run through cpp.  Instead, cpplib produces

foobar

The tokens are pasted when they shouldn't be.

The bug is in cpp_get_token, in the block beginning after the comment
/* If macro wants an arglist, verify that a '(' follows... */ This
block threw away whitespace provided by a macro expansion while
looking for the open parenthesis.  The fix is to push at least one
space into the token buffer rather than backtracking.

zw

1998-09-27 01:24 -0400  Zack Weinberg  <zack@rabi.phys.columbia.edu>

	* cpplib.c (cpp_get_token): When checking for an invocation of
	a macro with arguments, don't muck around with markers.  Just
	remember if we saw whitespace, and shove a space into the
	token buffer if so.  (Fixes bug causing unwanted token pasting.)

--- gcc/cpplib.c.bug	Sat Sep 26 21:55:20 1998
+++ gcc/cpplib.c	Sun Sep 27 00:15:56 1998
@@ -5086,32 +5086,36 @@
 	       decide this is not a macro call and leave things that way.  */
 	    if (hp->type == T_MACRO && hp->value.defn->nargs >= 0)
 	    {
-	      struct parse_marker macro_mark;
-	      int is_macro_call;
-	      while (CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile)))
-	        {
-		  cpp_buffer *next_buf;
-		  cpp_skip_hspace (pfile);
-		  if (PEEKC () != EOF)
-		    break;
-		  next_buf = CPP_PREV_BUFFER (CPP_BUFFER (pfile));
-		  (*CPP_BUFFER (pfile)->cleanup) (CPP_BUFFER (pfile), pfile);
-		  CPP_BUFFER (pfile) = next_buf;
-	        }
-	      parse_set_mark (&macro_mark, pfile);
-	      for (;;)
-		{
-		  cpp_skip_hspace (pfile);
+	      int was_whitespace = 0;
+
+	      do
+	      {
 		  c = PEEKC ();
-		  is_macro_call = c == '(';
-		  if (c != '\n')
-		    break;
-		  FORWARD (1);
-		}
-	      if (!is_macro_call)
-		parse_goto_mark (&macro_mark, pfile);
-	      parse_clear_mark (&macro_mark);
-	      if (!is_macro_call)
+		  if (c == EOF)
+		  {
+		      if (CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile)))
+		      {
+			  cpp_pop_buffer (pfile);
+			  continue;
+		      }
+		      else
+			  break;
+		  }
+
+		  if (is_space[c])
+		  {
+		      was_whitespace = 1;
+		      if (c == '\n')
+			  FORWARD (1);
+		      cpp_skip_hspace (pfile);
+		  }
+	      }
+	      while (c == EOF || is_space[c]);
+
+	      if (was_whitespace)
+		CPP_PUTC (pfile, ' ');
+
+	      if (c != '(')
 		return CPP_NAME;
 	    }
 	    /* This is now known to be a macro call.  */


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