This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
cpplib bug fix (macro expansion)
- To: egcs-patches at cygnus dot com
- Subject: cpplib bug fix (macro expansion)
- From: Zack Weinberg <zack at rabi dot columbia dot edu>
- Date: Sun, 27 Sep 1998 01:30:19 -0400
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 (¯o_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 (¯o_mark, pfile);
- parse_clear_mark (¯o_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. */