Some diagnostics e.g. -Wmaybe-uninitialized weren't showing underlines, despite being provided with range-based data.
Debugging showed that it the pertinent location was an ad-hoc location with a range: (gdb) p /x loc $9 = 0x8000002a (gdb) p line_table->location_adhoc_data_map.data[0x2a] $10 = {locus = 6919936, src_range = {m_start = 6919936, m_finish = 6921216}, data = 0x7ffff19a8480} (gdb) call inform (loc, "foo") test.c: In function 'test': test.c:173:10: note: foo return result; ^~~~~~ but the result from linemap_resolve_location here: location = linemap_resolve_location (line_table, location, LRK_SPELLING_LOCATION, NULL); was stripping away the ad-hoc location to just the locus: Value returned is $11 = 6919936 at the front of the token, thus losing the underline. The fix is to rework linemap_resolve_location to avoid bypassing ad-hoc locations, so that range data is available later. gcc/testsuite/ChangeLog: * gcc.dg/diagnostic-tree-expr-ranges-2.c: New file. libcpp/ChangeLog: * line-map.c (linemap_position_for_loc_and_offset): Handle ad-hoc locations. (linemap_macro_map_loc_unwind_toward_spelling): Add line_maps param. Handle ad-hoc locations. (linemap_location_in_system_header_p): Pass on "set" to call to linemap_macro_map_loc_unwind_toward_spelling. (linemap_macro_loc_to_spelling_point): Retain ad-hoc locations. Pass on "set" to call to linemap_macro_map_loc_unwind_toward_spelling. (linemap_resolve_location): Retain ad-hoc locations. Pass on "set" to call to linemap_macro_map_loc_unwind_toward_spelling. (linemap_unwind_toward_expansion): Pass on "set" to call to linemap_macro_map_loc_unwind_toward_spelling. --- .../gcc.dg/diagnostic-tree-expr-ranges-2.c | 23 ++++++++++++++++++ libcpp/line-map.c | 28 ++++++++++++---------- 2 files changed, 39 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/diagnostic-tree-expr-ranges-2.c diff --git a/gcc/testsuite/gcc.dg/diagnostic-tree-expr-ranges-2.c b/gcc/testsuite/gcc.dg/diagnostic-tree-expr-ranges-2.c new file mode 100644 index 0000000..302e233 --- /dev/null +++ b/gcc/testsuite/gcc.dg/diagnostic-tree-expr-ranges-2.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-Wuninitialized -fdiagnostics-show-caret" } */ + +int test_uninit_1 (void) +{ + int result; + return result; /* { dg-warning "uninitialized" } */ +/* { dg-begin-multiline-output "" } + return result; + ^~~~~~ + { dg-end-multiline-output "" } */ +} + +int test_uninit_2 (void) +{ + int result; + result += 3; /* { dg-warning "uninitialized" } */ +/* { dg-begin-multiline-output "" } + result += 3; + ~~~~~~~^~~~ + { dg-end-multiline-output "" } */ + return result; +} diff --git a/libcpp/line-map.c b/libcpp/line-map.c index 2cbd56a..6385fdf 100644 --- a/libcpp/line-map.c +++ b/libcpp/line-map.c @@ -46,7 +46,7 @@ static const line_map_macro* linemap_macro_map_lookup (struct line_maps *, static source_location linemap_macro_map_loc_to_def_point (const line_map_macro *, source_location); static source_location linemap_macro_map_loc_unwind_toward_spelling -(const line_map_macro *, source_location); +(line_maps *set, const line_map_macro *, source_location); static source_location linemap_macro_map_loc_to_exp_point (const line_map_macro *, source_location); static source_location linemap_macro_loc_to_spelling_point @@ -687,6 +687,9 @@ linemap_position_for_loc_and_offset (struct line_maps *set, { const line_map_ordinary * map = NULL; + if (IS_ADHOC_LOC (loc)) + loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus; + /* This function does not support virtual locations yet. */ if (linemap_assert_fails (!linemap_location_from_macro_expansion_p (set, loc))) @@ -907,14 +910,19 @@ linemap_macro_map_loc_to_def_point (const line_map_macro *map, In other words, this returns the xI location presented in the comments of line_map_macro above. */ source_location -linemap_macro_map_loc_unwind_toward_spelling (const line_map_macro* map, +linemap_macro_map_loc_unwind_toward_spelling (line_maps *set, + const line_map_macro* map, source_location location) { unsigned token_no; + if (IS_ADHOC_LOC (location)) + location = get_location_from_adhoc_loc (set, location); + linemap_assert (linemap_macro_expansion_map_p (map) && location >= MAP_START_LOCATION (map)); linemap_assert (location >= RESERVED_LOCATION_COUNT); + linemap_assert (!IS_ADHOC_LOC (location)); token_no = location - MAP_START_LOCATION (map); linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map)); @@ -1024,7 +1032,7 @@ linemap_location_in_system_header_p (struct line_maps *set, /* It's a token resulting from a macro expansion. */ source_location loc = - linemap_macro_map_loc_unwind_toward_spelling (macro_map, location); + linemap_macro_map_loc_unwind_toward_spelling (set, macro_map, location); if (loc < RESERVED_LOCATION_COUNT) /* This token might come from a built-in macro. Let's look at where that macro got expanded. */ @@ -1197,11 +1205,6 @@ linemap_macro_loc_to_spelling_point (struct line_maps *set, const line_map_ordinary **original_map) { struct line_map *map; - - if (IS_ADHOC_LOC (location)) - location = set->location_adhoc_data_map.data[location - & MAX_SOURCE_LOCATION].locus; - linemap_assert (set && location >= RESERVED_LOCATION_COUNT); while (true) @@ -1212,7 +1215,7 @@ linemap_macro_loc_to_spelling_point (struct line_maps *set, location = linemap_macro_map_loc_unwind_toward_spelling - (linemap_check_macro (map), + (set, linemap_check_macro (map), location); } @@ -1355,10 +1358,11 @@ linemap_resolve_location (struct line_maps *set, enum location_resolution_kind lrk, const line_map_ordinary **map) { + source_location locus = loc; if (IS_ADHOC_LOC (loc)) - loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus; + locus = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus; - if (loc < RESERVED_LOCATION_COUNT) + if (locus < RESERVED_LOCATION_COUNT) { /* A reserved location wasn't encoded in a map. Let's return a NULL map here, just like what linemap_ordinary_map_lookup @@ -1410,7 +1414,7 @@ linemap_unwind_toward_expansion (struct line_maps *set, loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus; resolved_location = - linemap_macro_map_loc_unwind_toward_spelling (macro_map, loc); + linemap_macro_map_loc_unwind_toward_spelling (set, macro_map, loc); resolved_map = linemap_lookup (set, resolved_location); if (!linemap_macro_expansion_map_p (resolved_map)) -- 1.8.5.3