This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH 04/11] Fix expansion point loc for macro-like tokens
- From: Dodji Seketeli <dodji at redhat dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Cc: Tom Tromey <tromey at redhat dot com>, Jason Merrill <jason at redhat dot com>, Gabriel Dos Reis <gdr at integrable-solutions dot net>
- Date: Tue, 10 Apr 2012 21:42:53 +0200
- Subject: [PATCH 04/11] Fix expansion point loc for macro-like tokens
- References: <m3hawr8wpz.fsf@redhat.com>
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.
Please look at the extensive comments I have added to cpp_get_token_1
to understand the details.
The easy fix here is to speculatively set the location of the returned
token before calling enter_macro_context.
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 (enter_macro_context): Update comment.
(cpp_get_token_1): Set virtual location before calling
enter_macro_context.
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 | 43 +++++++++++++++++++++++-
3 files changed, 49 insertions(+), 4 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 e0bfc31..e8ced2e 100644
--- a/libcpp/macro.c
+++ b/libcpp/macro.c
@@ -1005,8 +1005,9 @@ macro_real_token_count (const cpp_macro *macro)
directives among macro arguments, push another context containing
the pragma tokens before the yet-to-be-rescanned replacement list
and return two. Otherwise, we don't push a context and return
- zero. LOCATION is the location of the expansion point of the
- macro. */
+ zero. LOCATION is the location of the expansion point of the
+ macro. Note that callers might want to save pfile->context as this
+ function modifies it. */
static int
enter_macro_context (cpp_reader *pfile, cpp_hashnode *node,
const cpp_token *result, source_location location)
@@ -2316,6 +2317,44 @@ cpp_get_token_1 (cpp_reader *pfile, source_location *location)
if (pfile->state.prevent_expansion)
break;
+ /* We are currently expanding the macro
+ pfile->context->c.macro and we see that RESULT might be
+ a macro as well.
+
+ If we are not tracking locations accross macro
+ expansions, then set VIRT_LOC to the expansion point of
+ pfile->context->c.macro.
+
+ It's useful to do this in case RESULT is finally
+ considered to *NOT* be a macro by enter_macro_context
+ below. This can happen in cases like:
+
+ #define foo(x) // line 1
+ foo; // line 2
+
+ Preprocessing the above yields "foo;" because "foo" at
+ line 2 is not considered to be a macro; it is different
+ from the "function-like macro foo" defined at line 1.
+
+ So enter_macro_context below will return 0 on "foo" in
+ this case *and* will (surprisingly!) set
+ pfile->context->c.macro to NULL[1]. Meaning that "foo"
+ is just a normal token, rather than a macro to be
+ expanded.
+
+ [1]: Note that 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. */
+ if (!CPP_OPTION (pfile, track_macro_expansion)
+ && can_set
+ && pfile->context->c.macro != NULL)
+ virt_loc = pfile->invocation_location;
+
/* Conditional macros require that a predicate be evaluated
first. */
if ((node->flags & NODE_CONDITIONAL) != 0)
--
Dodji