Jakub Jelinek <ja...@redhat.com> writes: > On Mon, Feb 02, 2015 at 03:41:50PM +0100, Dodji Seketeli wrote: >> libcpp/ChangeLog: >> >> * internal.h (cpp_reader::top_most_macro_node): New data member. >> * macro.c (enter_macro_context): Pass the location of the end of >> the top-most invocation of the function-like macro, or the >> location of the expansion point of the top-most object-like macro. >> (cpp_get_token_1): Store the top-most macro node in the new >> pfile->top_most_macro_node data member. >> (_cpp_pop_context): Clear the new cpp_reader::top_most_macro_node >> data member. >> >> gcc/testsuite/ChangeLog: >> >> * gcc.dg/cpp/builtin-macro-1.c: New test case. > > Ok, thanks.
Thanks. The patch that finally passed bootstrap is the one below. It's slightly different in the condition I use to detect that we are popping the context of the top-most macro expansion stored in pfile->top_most_macro_node in _cpp_pop_context(). I now use: + if (macro == pfile->top_most_macro_node && context->prev == NULL) And the context->prev == NULL means, "this is the first macro expansion context on the the stack". I have also corrected a typo by s/poping/popping/. I don't know what I was thinking before. Bootstrapped and tested on x86_64-unknown-linux-gnu against trunk. libcpp/ChangeLog: * internal.h (cpp_reader::top_most_macro_node): New data member. * macro.c (enter_macro_context): Pass the location of the end of the top-most invocation of the function-like macro, or the location of the expansion point of the top-most object-like macro. (cpp_get_token_1): Store the top-most macro node in the new pfile->top_most_macro_node data member. (_cpp_pop_context): Clear the new cpp_reader::top_most_macro_node data member. gcc/testsuite/ChangeLog: * gcc.dg/cpp/builtin-macro-1.c: New test case. Signed-off-by: Dodji Seketeli <do...@redhat.com> --- gcc/testsuite/gcc.dg/cpp/builtin-macro-1.c | 28 +++++++++++++++++++++++++++ libcpp/internal.h | 5 +++++ libcpp/macro.c | 31 +++++++++++++++++++++++++++--- 3 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/cpp/builtin-macro-1.c diff --git a/gcc/testsuite/gcc.dg/cpp/builtin-macro-1.c b/gcc/testsuite/gcc.dg/cpp/builtin-macro-1.c new file mode 100644 index 0000000..90c2883 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/builtin-macro-1.c @@ -0,0 +1,28 @@ +/* Origin PR preprocessor/64803 + + This test ensures that the value the __LINE__ macro expands to is + constant and corresponds to the line of the closing parenthesis of + the top-most function-like macro expansion it's part of. + + { dg-do run } + { do-options -no-integrated-cpp } */ + +#include <assert.h> + +#define C(a, b) a ## b +#define L(x) C(L, x) +#define M(a) int L(__LINE__) = __LINE__; assert(L(__LINE__) == __LINE__); + +int +main() +{ + M(a + ); + + assert(L20 == 20); /* 20 is the line number of the + closing parenthesis of the + invocation of the M macro. Please + adjust in case the layout of this + file changes. */ + return 0; +} diff --git a/libcpp/internal.h b/libcpp/internal.h index 1a74020..96ccc19 100644 --- a/libcpp/internal.h +++ b/libcpp/internal.h @@ -421,6 +421,11 @@ struct cpp_reader macro invocation. */ source_location invocation_location; + /* This is the node representing the macro being expanded at + top-level. The value of this data member is valid iff + in_macro_expansion_p() returns TRUE. */ + cpp_hashnode *top_most_macro_node; + /* Nonzero if we are about to expand a macro. Note that if we are really expanding a macro, the function macro_of_context returns the macro being expanded and this flag is set to false. Client diff --git a/libcpp/macro.c b/libcpp/macro.c index 9571345..1e0a0b5 100644 --- a/libcpp/macro.c +++ b/libcpp/macro.c @@ -1228,7 +1228,24 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node, pfile->about_to_expand_macro_p = false; /* Handle built-in macros and the _Pragma operator. */ - return builtin_macro (pfile, node, location); + { + source_location loc; + if (/* The top-level macro invocation that triggered the expansion + we are looking at is with a standard macro ...*/ + !(pfile->top_most_macro_node->flags & NODE_BUILTIN) + /* ... and it's a function-like macro invocation. */ + && pfile->top_most_macro_node->value.macro->fun_like) + /* Then the location of the end of the macro invocation is the + location of the closing parenthesis. */ + loc = pfile->cur_token[-1].src_loc; + else + /* Otherwise, the location of the end of the macro invocation is + the location of the expansion point of that top-level macro + invocation. */ + loc = location; + + return builtin_macro (pfile, node, loc); + } } /* De-allocate the memory used by BUFF which is an array of instances @@ -2296,6 +2313,10 @@ _cpp_pop_context (cpp_reader *pfile) macro expansion. */ && macro_of_context (context->prev) != macro) macro->flags &= ~NODE_DISABLED; + + if (macro == pfile->top_most_macro_node && context->prev == NULL) + /* We are popping the context of the top-most macro node. */ + pfile->top_most_macro_node = NULL; } if (context->buff) @@ -2460,9 +2481,13 @@ cpp_get_token_1 (cpp_reader *pfile, source_location *location) { int ret = 0; /* If not in a macro context, and we're going to start an - expansion, record the location. */ + expansion, record the location and the top level macro + about to be expanded. */ if (!in_macro_expansion_p (pfile)) - pfile->invocation_location = result->src_loc; + { + pfile->invocation_location = result->src_loc; + pfile->top_most_macro_node = node; + } if (pfile->state.prevent_expansion) break; -- Dodji