Jason Merrill <ja...@redhat.com> writes: > On 05/15/2012 07:18 AM, Dodji Seketeli wrote: >> +paste_tokens (cpp_reader *pfile, source_location lhs_location, > > If in the long run we want the location passed in to be the ## > location, let's drop the "lhs" from the parameter name.
Dropped. > >> - const cpp_token *result = cpp_get_token (pfile); >> + const cpp_token *result = cpp_get_token_with_location (pfile, NULL); > > I find the difference between these two functions confusing, since you > aren't passing in a pointer for the location to go into. I see that > cpp_get_token_with_location sets pfile->set_invocation_location, which > is documented to mean > >> /* When expanding a macro at top-level, this is the location of the >> macro invocation. */ >> source_location invocation_location; >> >> /* True if this call to cpp_get_token should consider setting >> invocation_location. */ >> bool set_invocation_location; > > But presumably get_token_no_padding isn't only called when we're > starting to expand a top-level macro. And as far as I can tell the > value of invocation_location is only used when we aren't tracking > virtual locations anyway. So why does the change above fix the > testcase? It fixes the test case gcc.dg/cpp/paste12.c because that test case runs with -ftrack-macro-expansion turned off. Otherwise, you are right that the issue exists only when we aren't tracking virtual locations. FWIW, here is the updated patch I have. libcpp/ PR preprocessor/53229 * directives.c (get_token_no_padding): Allow use of virtual locations in diagnostics emitted by the processor when handling directives. Update comments. This fixes gcc.dg/cpp/paste12.c. * macro.c (paste_tokens): Take a virtual location parameter for the LHS of the pasting operator. Use it in diagnostics. Update comments. (paste_all_tokens): Tighten the assert. Propagate the location of the expansion point when no virtual locations are available. Pass the virtual location to paste_tokens. gcc/testsuite/ PR preprocessor/53229 * gcc.dg/cpp/paste6.c: Force to run without -ftrack-macro-expansion. * gcc.dg/cpp/paste8.c: Likewise. * gcc.dg/cpp/paste8-2.c: New test, like paste8.c but run with -ftrack-macro-expansion. * gcc.dg/cpp/paste12.c: Force to run without -ftrack-macro-expansion. * gcc.dg/cpp/paste12-2.c: New test, like paste12.c but run with -ftrack-macro-expansion. * gcc.dg/cpp/paste13.c: Likewise. * gcc.dg/cpp/paste14.c: Likewise. * gcc.dg/cpp/paste14-2.c: New test, like paste14.c but run with -ftrack-macro-expansion. * gcc.dg/cpp/paste18.c: New test. --- gcc/testsuite/gcc.dg/cpp/paste12-2.c | 11 +++++++++++ gcc/testsuite/gcc.dg/cpp/paste12.c | 5 ++++- gcc/testsuite/gcc.dg/cpp/paste13.c | 5 ++++- gcc/testsuite/gcc.dg/cpp/paste14-2.c | 11 +++++++++++ gcc/testsuite/gcc.dg/cpp/paste14.c | 5 ++++- gcc/testsuite/gcc.dg/cpp/paste18.c | 16 ++++++++++++++++ gcc/testsuite/gcc.dg/cpp/paste6.c | 5 ++++- gcc/testsuite/gcc.dg/cpp/paste8-2.c | 15 +++++++++++++++ gcc/testsuite/gcc.dg/cpp/paste8.c | 2 +- libcpp/directives.c | 7 +++++-- libcpp/macro.c | 25 +++++++++++++++++-------- 11 files changed, 92 insertions(+), 15 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/cpp/paste12-2.c create mode 100644 gcc/testsuite/gcc.dg/cpp/paste14-2.c create mode 100644 gcc/testsuite/gcc.dg/cpp/paste18.c create mode 100644 gcc/testsuite/gcc.dg/cpp/paste8-2.c diff --git a/gcc/testsuite/gcc.dg/cpp/paste12-2.c b/gcc/testsuite/gcc.dg/cpp/paste12-2.c new file mode 100644 index 0000000..6e2e4f1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/paste12-2.c @@ -0,0 +1,11 @@ +/* + { dg-options "-ftrack-macro-expansion=2" } + { dg-do preprocess } + */ + +/* Test correct diagnostics when pasting in #include. + Source: PR preprocessor/6780. */ + +#define inc2(a,b) <##a.b> /* { dg-error "pasting \"<\" and \"stdio\" does not" } */ +#define INC(X) inc2(X,h) +#include INC(stdio) diff --git a/gcc/testsuite/gcc.dg/cpp/paste12.c b/gcc/testsuite/gcc.dg/cpp/paste12.c index e61ec51..3e0f7b9 100644 --- a/gcc/testsuite/gcc.dg/cpp/paste12.c +++ b/gcc/testsuite/gcc.dg/cpp/paste12.c @@ -1,4 +1,7 @@ -/* { dg-do preprocess } */ +/* + { dg-options "-ftrack-macro-expansion=0" } + { dg-do preprocess } +*/ /* Test correct diagnostics when pasting in #include. Source: PR preprocessor/6780. */ diff --git a/gcc/testsuite/gcc.dg/cpp/paste13.c b/gcc/testsuite/gcc.dg/cpp/paste13.c index 62c72d4..f0f4fd8 100644 --- a/gcc/testsuite/gcc.dg/cpp/paste13.c +++ b/gcc/testsuite/gcc.dg/cpp/paste13.c @@ -1,6 +1,9 @@ /* Copyright (C) 2000 Free Software Foundation, Inc. */ -/* { dg-do preprocess } */ +/* + { dg-options "-ftrack-macro-expansion=0" } + { dg-do preprocess } +*/ /* This used to be recognized as a comment when lexing after pasting spellings. Neil Booth, 9 Oct 2002. */ diff --git a/gcc/testsuite/gcc.dg/cpp/paste14-2.c b/gcc/testsuite/gcc.dg/cpp/paste14-2.c new file mode 100644 index 0000000..3b23ada --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/paste14-2.c @@ -0,0 +1,11 @@ +/* PR preprocessor/28709 */ +/* + { dg-options "-ftrack-macro-expansion=2" } + { dg-do preprocess } +*/ + +#define foo - ## >> /* { dg-error "pasting \"-\" and \">>\"" } */ +foo +#define bar = ## == /* { dg-error "pasting \"=\" and \"==\"" } */ +bar + diff --git a/gcc/testsuite/gcc.dg/cpp/paste14.c b/gcc/testsuite/gcc.dg/cpp/paste14.c index ec243c2..043d5e5 100644 --- a/gcc/testsuite/gcc.dg/cpp/paste14.c +++ b/gcc/testsuite/gcc.dg/cpp/paste14.c @@ -1,5 +1,8 @@ /* PR preprocessor/28709 */ -/* { dg-do preprocess } */ +/* + { dg-options "-ftrack-macro-expansion=0" } + { dg-do preprocess } +*/ #define foo - ## >> foo /* { dg-error "pasting \"-\" and \">>\"" } */ diff --git a/gcc/testsuite/gcc.dg/cpp/paste18.c b/gcc/testsuite/gcc.dg/cpp/paste18.c new file mode 100644 index 0000000..2888144 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/paste18.c @@ -0,0 +1,16 @@ +/* + { dg-options "-ftrack-macro-expansion=2" } + { dg-do compile } + */ + +struct x { + int i; +}; +struct x x; + +#define TEST(X) x.##X /* { dg-error "pasting\[^\n\r\]*does not give\[^\n\r\]*token" } */ + +void foo (void) +{ + TEST(i) = 0; +} diff --git a/gcc/testsuite/gcc.dg/cpp/paste6.c b/gcc/testsuite/gcc.dg/cpp/paste6.c index ac9ae39..a4e70e4 100644 --- a/gcc/testsuite/gcc.dg/cpp/paste6.c +++ b/gcc/testsuite/gcc.dg/cpp/paste6.c @@ -2,7 +2,10 @@ actual arguments. Original bug exposed by Linux kernel. Problem reported by Jakub Jelinek <ja...@redhat.com>. */ -/* { dg-do compile } */ +/* + { dg-options "-ftrack-macro-expansion=0" } + { dg-do compile } +*/ extern int foo(int x); diff --git a/gcc/testsuite/gcc.dg/cpp/paste8-2.c b/gcc/testsuite/gcc.dg/cpp/paste8-2.c new file mode 100644 index 0000000..c037e99 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/paste8-2.c @@ -0,0 +1,15 @@ +/* { dg-do preprocess } */ +/* { dg-options "-ftrack-macro-expansion=2" } */ + +int foo(int, ...); + +#define a(x, y...) foo(x, ##y) +a(1) +a(1, 2, 3) +#define b(x, y, z...) foo(x, ##y) /* { dg-error "valid preprocessing token" } */ +b(1, 2, 3) +#define c(x, y, z...) foo(x, ##z) +c(1, 2) +c(1, 2, 3) +#define d(x) fo(##x) /* { dg-error "valid preprocessing token" } */ +d(1) diff --git a/gcc/testsuite/gcc.dg/cpp/paste8.c b/gcc/testsuite/gcc.dg/cpp/paste8.c index ab01779..db1416c 100644 --- a/gcc/testsuite/gcc.dg/cpp/paste8.c +++ b/gcc/testsuite/gcc.dg/cpp/paste8.c @@ -1,5 +1,5 @@ /* { dg-do preprocess } */ -/* { dg-options "" } */ +/* { dg-options "-ftrack-macro-expansion=0" } */ int foo(int, ...); diff --git a/libcpp/directives.c b/libcpp/directives.c index e46280e..e161810 100644 --- a/libcpp/directives.c +++ b/libcpp/directives.c @@ -1660,13 +1660,16 @@ do_pragma_dependency (cpp_reader *pfile) free ((void *) fname); } -/* Get a token but skip padding. */ +/* Get a token but skip padding. + + Handles macro expansion and allows the use of virtual locations in + diagnostics emitted by the preprocessor. */ static const cpp_token * get_token_no_padding (cpp_reader *pfile) { for (;;) { - const cpp_token *result = cpp_get_token (pfile); + const cpp_token *result = cpp_get_token_with_location (pfile, NULL); if (result->type != CPP_PADDING) return result; } diff --git a/libcpp/macro.c b/libcpp/macro.c index c4e2a23..04810b3 100644 --- a/libcpp/macro.c +++ b/libcpp/macro.c @@ -100,7 +100,8 @@ static void expand_arg (cpp_reader *, macro_arg *); static const cpp_token *new_string_token (cpp_reader *, uchar *, unsigned int); static const cpp_token *stringify_arg (cpp_reader *, macro_arg *); static void paste_all_tokens (cpp_reader *, const cpp_token *); -static bool paste_tokens (cpp_reader *, const cpp_token **, const cpp_token *); +static bool paste_tokens (cpp_reader *, source_location, + const cpp_token **, const cpp_token *); static void alloc_expanded_arg_mem (cpp_reader *, macro_arg *, size_t); static void ensure_expanded_arg_room (cpp_reader *, macro_arg *, size_t, size_t *); static void delete_macro_args (_cpp_buff*, unsigned num_args); @@ -544,9 +545,11 @@ stringify_arg (cpp_reader *pfile, macro_arg *arg) /* Try to paste two tokens. On success, return nonzero. In any case, PLHS is updated to point to the pasted token, which is - guaranteed to not have the PASTE_LEFT flag set. */ + guaranteed to not have the PASTE_LEFT flag set. LOCATION is + the virtual location used for error reporting. */ static bool -paste_tokens (cpp_reader *pfile, const cpp_token **plhs, const cpp_token *rhs) +paste_tokens (cpp_reader *pfile, source_location location, + const cpp_token **plhs, const cpp_token *rhs) { unsigned char *buf, *end, *lhsend; cpp_token *lhs; @@ -590,7 +593,7 @@ paste_tokens (cpp_reader *pfile, const cpp_token **plhs, const cpp_token *rhs) /* Mandatory error for all apart from assembler. */ if (CPP_OPTION (pfile, lang) != CLK_ASM) - cpp_error (pfile, CPP_DL_ERROR, + cpp_error_with_line (pfile, CPP_DL_ERROR, location, 0, "pasting \"%s\" and \"%s\" does not give a valid preprocessing token", buf, cpp_token_as_text (pfile, rhs)); return false; @@ -615,9 +618,10 @@ paste_all_tokens (cpp_reader *pfile, const cpp_token *lhs) cpp_context *context = pfile->context; source_location virt_loc = 0; - /* We must have been called on a token that appears at the left - hand side of a ## operator. */ - if (!(lhs->flags & PASTE_LEFT)) + /* We are expanding a macro and we must have been called on a token + that appears at the left hand side of a ## operator. */ + if (macro_of_context (pfile->context) == NULL + || (!(lhs->flags & PASTE_LEFT))) abort (); if (context->tokens_kind == TOKENS_KIND_EXTENDED) @@ -628,6 +632,11 @@ paste_all_tokens (cpp_reader *pfile, const cpp_token *lhs) resulting pasted token to have the location of the current *LHS, though. */ virt_loc = context->c.mc->cur_virt_loc[-1]; + else + /* We are not tracking macro expansion. So the best virtual + location we can get here is the expansion point of the macro we + are currently expanding. */ + virt_loc = pfile->invocation_location; do { @@ -661,7 +670,7 @@ paste_all_tokens (cpp_reader *pfile, const cpp_token *lhs) if (rhs->flags & PASTE_LEFT) abort (); } - if (!paste_tokens (pfile, &lhs, rhs)) + if (!paste_tokens (pfile, virt_loc, &lhs, rhs)) break; } while (rhs->flags & PASTE_LEFT); -- 1.7.6.5 -- Dodji