This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Patch: PR preprocessor/28709
- From: Tom Tromey <tromey at redhat dot com>
- To: Gcc Patch List <gcc-patches at gcc dot gnu dot org>
- Date: 29 Dec 2006 12:34:25 -0700
- Subject: Patch: PR preprocessor/28709
- Reply-to: tromey at redhat dot com
This patch fixes PR preprocessor/28709.
The bug is a very minor one. If the user attempts to paste "-" and
">>", cpp will emit a half-pasted "->" token. The invalid paste is
correctly diagnosed, but the parser emits an error that refers to
"->", which is somewhat confusing.
The problem is that paste_tokens may modify the LHS of the paste
operation. The patch fixes the bug by making a copy of the LHS while
removing the PASTE_LEFT flag and preserving the old location. The
actual patch is somewhat involved due to 'const' and a clarification
so that we only use the 'lhs' variable for one purpose.
Bootstrapped and regression tested on x86 FC6. Test case included.
Ok?
Tom
:ADDPATCH preprocessor:
libcpp
2006-12-29 Tom Tromey <tromey@redhat.com>
PR preprocessor/28709:
* macro.c (paste_tokens): Remove PASTE_LEFT from the old lhs.
gcc/testsuite
2006-12-29 Tom Tromey <tromey@redhat.com>
PR preprocessor/28709:
* gcc.dg/cpp/pr28709.c: New file.
Index: libcpp/macro.c
===================================================================
--- libcpp/macro.c (revision 120244)
+++ libcpp/macro.c (working copy)
@@ -431,19 +432,18 @@
paste_tokens (cpp_reader *pfile, const cpp_token **plhs, const cpp_token *rhs)
{
unsigned char *buf, *end, *lhsend;
- const cpp_token *lhs;
+ cpp_token *lhs;
unsigned int len;
- lhs = *plhs;
- len = cpp_token_len (lhs) + cpp_token_len (rhs) + 1;
+ len = cpp_token_len (*plhs) + cpp_token_len (rhs) + 1;
buf = (unsigned char *) alloca (len);
- end = lhsend = cpp_spell_token (pfile, lhs, buf, false);
+ end = lhsend = cpp_spell_token (pfile, *plhs, buf, false);
/* Avoid comment headers, since they are still processed in stage 3.
It is simpler to insert a space here, rather than modifying the
lexer to ignore comments in some circumstances. Simply returning
false doesn't work, since we want to clear the PASTE_LEFT flag. */
- if (lhs->type == CPP_DIV && rhs->type != CPP_EQ)
+ if ((*plhs)->type == CPP_DIV && rhs->type != CPP_EQ)
*end++ = ' ';
end = cpp_spell_token (pfile, rhs, end, false);
*end = '\n';
@@ -453,13 +453,22 @@
/* Set pfile->cur_token as required by _cpp_lex_direct. */
pfile->cur_token = _cpp_temp_token (pfile);
- *plhs = _cpp_lex_direct (pfile);
+ lhs = _cpp_lex_direct (pfile);
if (pfile->buffer->cur != pfile->buffer->rlimit)
{
+ source_location saved_loc = lhs->src_loc;
+
_cpp_pop_buffer (pfile);
_cpp_backup_tokens (pfile, 1);
*lhsend = '\0';
+ /* We have to remove the PASTE_LEFT flag from the old lhs, but
+ we want to keep the new location. */
+ *lhs = **plhs;
+ *plhs = lhs;
+ lhs->src_loc = saved_loc;
+ lhs->flags &= ~PASTE_LEFT;
+
/* Mandatory error for all apart from assembler. */
if (CPP_OPTION (pfile, lang) != CLK_ASM)
cpp_error (pfile, CPP_DL_ERROR,
@@ -468,6 +477,7 @@
return false;
}
+ *plhs = lhs;
_cpp_pop_buffer (pfile);
return true;
}
Index: gcc/testsuite/gcc.dg/cpp/pr28709.c
===================================================================
--- gcc/testsuite/gcc.dg/cpp/pr28709.c (revision 0)
+++ gcc/testsuite/gcc.dg/cpp/pr28709.c (revision 0)
@@ -0,0 +1,8 @@
+/* Copyright (C) 2006 Free Software Foundation, Inc. */
+/* PR preprocessor/28709 */
+
+/* { dg-do compile } */
+#define foo - ## >>
+foo;
+/* { dg-error "expected identifier.*'-'" "" { target *-*-* } 6 } */
+/* { dg-error pasting "" { target *-*-* } 6 } */