This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
cpplib: fix for another obscure macro-expansion bug
- To: egcs-patches at cygnus dot com
- Subject: cpplib: fix for another obscure macro-expansion bug
- From: Zack Weinberg <zack at rabi dot columbia dot edu>
- Date: Sun, 27 Sep 1998 13:04:10 -0400
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;