diff options
author | dodji <dodji@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-04-30 11:42:12 +0000 |
---|---|---|
committer | dodji <dodji@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-04-30 11:42:12 +0000 |
commit | bd172d6184a05fe46afdde1801ba73a4fc250f52 (patch) | |
tree | 38dd74c3ec31ffcb6460e6b4189050b796ba31ca /libcpp | |
parent | 391076554ccd40fa818825bff3afa4c62ce2d9a9 (diff) | |
download | gcc-bd172d6184a05fe46afdde1801ba73a4fc250f52.tar.gz |
Strip "<built-in>" loc from displayed expansion context
Now that diagnostics for tokens coming from macro expansions point to
the spelling location of the relevant token (and then displays the
context of the expansion), some ugly (not so seldom) corner cases can
happen.
When the relevant token is a built-in token (which means the location
of that token is BUILTINS_LOCATION) the location prefix displayed to
the user in the diagnostic line is the "<built-in>:0:0" string. For
instance:
<built-in>:0:0: warning: conversion to 'float' alters 'int' constant value
For the user, I think this is surprising and useless.
A more user-friendly approach would be to refer to the first location
that (in the reported macro expansion context) is for a location in
real source code, like what is shown in the new test case
gcc/testsuite/g++.dg/warn/Wconversion-real-integer2.C accompanying
this patch.
To do this, I am making the line-map module provide a new
linemap_unwind_to_first_non_reserved_loc function that resolves a
virtual location to the first spelling location that is in real source
code.
I am then using that facility in the diagnostics printing module and
in the macro unwinder to avoid printing diagnostics lines that refer
to the locations for built-ins or more generally for reserved
locations. Note that when I start the dance of skipping a built-in
location I also skip locations that are in system headers, because it
turned out that a lot of those built-ins are actually used in system
headers (e.g, "#define INT_MAX __INT_MAX__" where __INT_MAX__ is a
built-in).
Besides the user-friendliness gain, this patch allows a number of
regression tests to PASS unchanged with and without
-ftrack-macro-expansion.
Tested and bootstrapped on x86_64-unknown-linux-gnu against trunk.
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/
* include/line-map.h (linemap_unwind_toward_expansion): Fix typo
in comment.
(linemap_unwind_to_first_non_reserved_loc): Declare new function.
* line-map.c (linemap_unwind_to_first_non_reserved_loc): Define
new function.
gcc/
* input.c (expand_location_1): When expanding to spelling location
in a context of a macro expansion, skip reserved system header
locations. Update comments. * tree-diagnostic.c
(maybe_unwind_expanded_macro_loc): Likewise.
gcc/testsuite/
* g++.dg/warn/Wconversion-real-integer2.C: New test.
* g++.dg/warn/Wconversion-real-integer-3.C: Likewise.
* g++.dg/warn/conversion-real-integer-3.h: New header used by the
new test above.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@186970 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libcpp')
-rw-r--r-- | libcpp/ChangeLog | 7 | ||||
-rw-r--r-- | libcpp/include/line-map.h | 20 | ||||
-rw-r--r-- | libcpp/line-map.c | 49 |
3 files changed, 75 insertions, 1 deletions
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index 5e93396ac75..2c05214d4f7 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,5 +1,12 @@ 2012-04-30 Dodji Seketeli <dodji@redhat.com> + Strip "<built-in>" loc from displayed expansion context + * include/line-map.h (linemap_unwind_toward_expansion): Fix typo + in comment. + (linemap_unwind_to_first_non_reserved_loc): Declare new function. + * line-map.c (linemap_unwind_to_first_non_reserved_loc): Define + new function. + Fix expansion point loc for macro-like tokens * macro.c (macro_of_context): New static function. (_cpp_push_token_context, push_extended_tokens_context): If the diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h index 22e2f0fc3c6..1c81fc52ad7 100644 --- a/libcpp/include/line-map.h +++ b/libcpp/include/line-map.h @@ -666,12 +666,30 @@ source_location linemap_resolve_location (struct line_maps *, location L of the point where M got expanded. If L is a spelling location inside a macro expansion M', then this function returns the point where M' was expanded. LOC_MAP is an output parameter. - When non-NULL, *LOC_MAP is set the the map of the returned + When non-NULL, *LOC_MAP is set to the map of the returned location. */ source_location linemap_unwind_toward_expansion (struct line_maps *, source_location loc, const struct line_map **loc_map); +/* If LOC is the virtual location of a token coming from the expansion + of a macro M and if its spelling location is reserved (e.g, a + location for a built-in token), then this function unwinds (using + linemap_unwind_toward_expansion) the location until a location that + is not reserved and is not in a system header is reached. In other + words, this unwinds the reserved location until a location that is + in real source code is reached. + + Otherwise, if the spelling location for LOC is not reserved or if + LOC doesn't come from the expansion of a macro, the function + returns LOC as is and *MAP is not touched. + + *MAP is set to the map of the returned location if the later is + different from LOC. */ +source_location linemap_unwind_to_first_non_reserved_loc (struct line_maps *, + source_location loc, + const struct line_map **map); + /* Expand source code location LOC and return a user readable source code location. LOC must be a spelling (non-virtual) location. If it's a location < RESERVED_LOCATION_COUNT a zeroed expanded source diff --git a/libcpp/line-map.c b/libcpp/line-map.c index 106a4b515a7..6e514e5531a 100644 --- a/libcpp/line-map.c +++ b/libcpp/line-map.c @@ -1114,6 +1114,55 @@ linemap_unwind_toward_expansion (struct line_maps *set, return resolved_location; } +/* If LOC is the virtual location of a token coming from the expansion + of a macro M and if its spelling location is reserved (e.g, a + location for a built-in token), then this function unwinds (using + linemap_unwind_toward_expansion) the location until a location that + is not reserved and is not in a sytem header is reached. In other + words, this unwinds the reserved location until a location that is + in real source code is reached. + + Otherwise, if the spelling location for LOC is not reserved or if + LOC doesn't come from the expansion of a macro, the function + returns LOC as is and *MAP is not touched. + + *MAP is set to the map of the returned location if the later is + different from LOC. */ +source_location +linemap_unwind_to_first_non_reserved_loc (struct line_maps *set, + source_location loc, + const struct line_map **map) +{ + source_location resolved_loc; + const struct line_map *map0 = NULL, *map1 = NULL; + + map0 = linemap_lookup (set, loc); + if (!linemap_macro_expansion_map_p (map0)) + return loc; + + resolved_loc = linemap_resolve_location (set, loc, + LRK_SPELLING_LOCATION, + &map1); + + if (resolved_loc >= RESERVED_LOCATION_COUNT + && !LINEMAP_SYSP (map1)) + return loc; + + while (linemap_macro_expansion_map_p (map0) + && (resolved_loc < RESERVED_LOCATION_COUNT + || LINEMAP_SYSP (map1))) + { + loc = linemap_unwind_toward_expansion (set, loc, &map0); + resolved_loc = linemap_resolve_location (set, loc, + LRK_SPELLING_LOCATION, + &map1); + } + + if (map != NULL) + *map = map0; + return loc; +} + /* Expand source code location LOC and return a user readable source code location. LOC must be a spelling (non-virtual) location. If it's a location < RESERVED_LOCATION_COUNT a zeroed expanded source |