diff options
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/cpp/builtin-macro-1.c | 28 | ||||
-rw-r--r-- | libcpp/ChangeLog | 12 | ||||
-rw-r--r-- | libcpp/internal.h | 5 | ||||
-rw-r--r-- | libcpp/macro.c | 31 |
5 files changed, 78 insertions, 3 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2039b4c4697..c85fa087d60 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-02-03 <dodji@redhat.com> + + PR preprocessor/64803 + * gcc.dg/cpp/builtin-macro-1.c: New test case. + 2015-02-02 Jan Hubicka <hubicka@ucw.cz> * g++.dg/ipa/devirt-37.C: Disable early inlining. 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 00000000000..90c2883b471 --- /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/ChangeLog b/libcpp/ChangeLog index 5dd64468a90..325f7060963 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,3 +1,15 @@ +2015-02-03 <dodji@redhat.com> + + PR preprocessor/64803 + * 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. + 2015-01-30 Szabolcs Nagy <szabolcs.nagy@arm.com> * lex.c (search_line_fast): Change __ARM_NEON__ to __ARM_NEON. diff --git a/libcpp/internal.h b/libcpp/internal.h index 1a7402079ce..96ccc19e447 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 95713450c27..1e0a0b560ba 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; |