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: fix for another obscure macro-expansion bug



cpplib mis-processes the following fragment:

#define FLT_MIN_EXP (-125)
#define FLT FLT

#define P(a,b) P1(a,b)
#define P1(a,b) a##b
#define MIN_EXP P(FLT,_MIN_EXP)

int flt_min_exp = MIN_EXP;

`FLT' gets tagged with a no-reexpand escape.  Then P1 pastes together
`FLT' and `_MIN_EXP' but doesn't remove the escape, so it's applied to
the pasted token.

Here is a patch.

zw

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

	* cpplib.c (macroexpand): If arg->raw_before or
	arg->raw_after, remove any no-reexpansion escape at the
	beginning of the pasted token.  Correct handling of whitespace
	markers and no-reexpand markers at the end if arg->raw_after.

--- cpplib.c.bug2	Sun Sep 27 12:11:19 1998
+++ cpplib.c	Sun Sep 27 12:38:44 1998
@@ -2874,11 +2874,6 @@
 		  while (p1 != l1 && is_space[*p1]) p1++;
 		  while (p1 != l1 && is_idchar[*p1])
 		    xbuf[totlen++] = *p1++;
-		  /* Delete any no-reexpansion marker that follows
-		     an identifier at the beginning of the argument
-		     if the argument is concatenated with what precedes it.  */
-		  if (p1[0] == '@' && p1[1] == '-')
-		    p1 += 2;
 		}
 	      if (ap->raw_after)
 		{
@@ -2887,20 +2882,37 @@
 		  while (p1 != l1)
 		    {
 		      if (is_space[l1[-1]]) l1--;
+		      else if (l1[-1] == '@')
+		        {
+			  U_CHAR *p2 = l1 - 1;
+			  /* If whitespace is preceded by an odd number
+			     of `@' signs, the last `@' was a whitespace
+			     marker; drop it too. */
+			  while (p2 != p1 && p2[-1] == '@') p2--;
+			  if ((l1 - 1 - p2) & 1)
+			    l1--;
+			  break;
+			}
 		      else if (l1[-1] == '-')
 			{
 			  U_CHAR *p2 = l1 - 1;
-			  /* If a `-' is preceded by an odd number of newlines then it
-			     and the last newline are a no-reexpansion marker.  */
-			  while (p2 != p1 && p2[-1] == '\n') p2--;
-			  if ((l1 - 1 - p2) & 1) {
+			  /* If a `-' is preceded by an odd number of
+			     `@' signs then it and the last `@' are
+			     a no-reexpansion marker.  */
+			  while (p2 != p1 && p2[-1] == '@') p2--;
+			  if ((l1 - 1 - p2) & 1)
 			    l1 -= 2;
-			  }
-			  else break;
+			  else
+			    break;
 			}
 		      else break;
 		    }
 		}
+
+	      /* Delete any no-reexpansion marker that precedes
+		 an identifier at the beginning of the argument. */
+	      if (p1[0] == '@' && p1[1] == '-')
+		p1 += 2;
 
 	      bcopy (p1, xbuf + totlen, l1 - p1);
 	      totlen += l1 - p1;


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