Jason Merrill <ja...@redhat.com> writes: > On 04/10/2012 03:42 PM, Dodji Seketeli wrote: >> In that case, besides returning NULL, enter_macro_context sets >> pfile->context->c.macro to NULL, making cpp_get_token_1 forget to set >> the location of the "vari" to the expansion point of A. > > This seems like a bug that should be fixed rather than worked around; > we are still expanding A.
Right. Below is an updated patch (with an updated introductory text) that addresses the core of the issue. Consider the test case gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-5.c. Its interesting part is: #define A(x) vari x /* line 7. */ #define vari(x) #define B , varj int A(B) ; /* line 10. */ In its initial version, this test was being pre-processed as: # 1 "gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-5.c" # 1 "build/gcc//" # 1 "<command-line>" # 1 "gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-5.c" # 10 "gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-5.c" int # 7 "gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-5.c" vari , varj ; Note how "int" and "vari" are on separate lines, whereas "int" and ", varj" are on the same line. This looks like a bug to me, even independantly from the macro location tracking work. With macro location tracking turned on, the preprocessed output becomes: # 1 "gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-5.c" # 1 "<command-line>" # 1 "gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-5.c" # 10 "gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-5.c" int vari , varj ; Which, IMO, is what we'd expect. This is due to an unexpected side effect of enter_macro_context when passed a token that might look like a function-like macro at first sight, but that it eventually considers to not be a macro after all. This is the case for the "vari" token which looks like a macro when it is first lexed, but is eventually considered to be a normal token by enter_macro_context because it's not used as a function-like macro invocation. In that case, besides returning NULL, enter_macro_context sets pfile->context->c.macro to NULL, making cpp_get_token_1 forget to set the location of the "vari" to the expansion point of A. enter_macro_context sets pfile->context->c.macro to NULL in that case because funlike_invocation_p reads one token pass "foo", sees that there is no '(' token, so we are not invoking the function-like parameter. It then puts the tokens (which it has read after "foo") back into the tokens stream by calling _cpp_push_token_context on it, which sets pfile->context->c.macro to NULL. The fix here is to prevent funlike_invocation_p from forgetting the current "macro-ness". Tested on x86_64-unknown-linux-gnu against trunk. Now this test has the same output with and without tracking locations accross macro expansions. Note that the bootstrap with -ftrack-macro-expansion exhibits other separate issues that are addressed in subsequent patches. This patch just fixes one class of problems. The patch does pass bootstrap with -ftrack-macro-expansion turned off, though. libcpp/ * macro.c (funlike_invocation_p): Don't forget macro-ness. gcc/testsuite/ * gcc.dg/debug/dwarf2/pr41445-5.c: Adjust. * gcc.dg/debug/dwarf2/pr41445-6.c: Likewise. --- gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-5.c | 5 ++++- gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-6.c | 5 ++++- libcpp/macro.c | 12 +++++++++++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-5.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-5.c index 03af604..d21acd5 100644 --- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-5.c +++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-5.c @@ -9,6 +9,9 @@ #define B , varj int A(B) ; -/* { dg-final { scan-assembler "DW_TAG_variable\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\"vari\[^\\r\\n\]*DW_AT_name(\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*DW_AT_)*\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\[^0-9a-fA-FxX](0x)?7\[^0-9a-fA-FxX]\[^\\r\\n\]*DW_AT_decl_line" } } */ +/* We want to check that both vari and varj have the same line + number. */ + +/* { dg-final { scan-assembler "DW_TAG_variable\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\"vari\[^\\r\\n\]*DW_AT_name(\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*DW_AT_)*\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\[^0-9a-fA-FxX](0xa|10)\[^0-9a-fA-FxX]\[^\\r\\n\]*DW_AT_decl_line" } } */ /* { dg-final { scan-assembler "DW_TAG_variable\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\"varj\[^\\r\\n\]*DW_AT_name(\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*DW_AT_)*\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\[^0-9a-fA-FxX](0xa|10)\[^0-9a-fA-FxX]\[^\\r\\n\]*DW_AT_decl_line" } } */ /* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-6.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-6.c index 8aa37d1..d6d79cc 100644 --- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-6.c +++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-6.c @@ -4,5 +4,8 @@ #include "pr41445-5.c" -/* { dg-final { scan-assembler "DW_TAG_variable\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\"vari\[^\\r\\n\]*DW_AT_name(\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*DW_AT_)*\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\[^0-9a-fA-FxX](0x)?7\[^0-9a-fA-FxX]\[^\\r\\n\]*DW_AT_decl_line" } } */ +/* We want to check that both vari and varj have the same line + number. */ + +/* { dg-final { scan-assembler "DW_TAG_variable\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\"vari\[^\\r\\n\]*DW_AT_name(\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*DW_AT_)*\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\[^0-9a-fA-FxX](0xa|10)?\[^0-9a-fA-FxX]\[^\\r\\n\]*DW_AT_decl_line" } } */ /* { dg-final { scan-assembler "DW_TAG_variable\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\"varj\[^\\r\\n\]*DW_AT_name(\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*DW_AT_)*\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\[^0-9a-fA-FxX](0xa|10)\[^0-9a-fA-FxX]\[^\\r\\n\]*DW_AT_decl_line" } } */ diff --git a/libcpp/macro.c b/libcpp/macro.c index f4638c4..672020a 100644 --- a/libcpp/macro.c +++ b/libcpp/macro.c @@ -979,7 +979,17 @@ funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node, too difficult. We re-insert it in its own context. */ _cpp_backup_tokens (pfile, 1); if (padding) - _cpp_push_token_context (pfile, NULL, padding, 1); + { + /* If the first token we got was a padding token, let's put + it back into the stream so that cpp_get_token will get it + first; and if we are currently expanding a macro, don't + forget that information. */ + cpp_hashnode *macro = + (pfile->context->tokens_kind == TOKENS_KIND_EXTENDED) + ? pfile->context->c.mc->macro_node + : pfile->context->c.macro; + _cpp_push_token_context (pfile, macro, padding, 1); + } } return NULL; -- 1.7.6.5 -- Dodji