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

Reply via email to