PR c++/70105: prevent nonsensical underline spew for macro expansions

diagnostic_show_locus can sometimes do the wrong thing when handling
expressions built up from macros.

PR c++/70105 (currently marked as a P3 regression) has an example of
a diagnostic where over 500 lines of irrelevant source are printed,
and underlined, giving >1000 lines of useless spew to stderr.

This patch adds extra sanitization to diagnostic-show-locus.c, so that
we only attempt to print underlines and secondary locations if such
locations are "sufficiently sane" relative to the primary location
of a diagnostic.

This "sufficiently sane" condition is implemented by a new helper
function compatible_locations_p, which requires such locations to
have the same macro expansion hierarchy as the primary location,
using linemap_macro_map_loc_unwind_toward_spelling, effectively
mimicing the expansion performed by LRK_SPELLING_LOCATION.

This may be too strong a condition, but it effectively fixes
PR c++/70105, without removing any underlines in my testing.

Successfully bootstrapped&regrtested in combination with the previous
patch on x86_64-pc-linux-gnu; adds 15 new PASS results to g++.sum
and 4 new PASS results to gcc.sum.

gcc/ChangeLog:
	PR c/68473
	PR c++/70105
	* diagnostic-show-locus.c (compatible_locations_p): New function.
	(layout::layout): Sanitize ranges using compatible_locations_p.

gcc/testsuite/ChangeLog:
	PR c/68473
	PR c++/70105
	* g++.dg/diagnostic/pr70105.C: New test.
	* gcc.dg/plugin/diagnostic-test-expressions-1.c (foo): New decl.
	(test_multiple_ordinary_maps): New test function.

libcpp/ChangeLog:
	PR c/68473
	PR c++/70105
	* line-map.c (linemap_macro_map_loc_unwind_toward_spelling): Move
	decl...
	* include/line-map.h
	(linemap_macro_map_loc_unwind_toward_spelling): ...here,
	converting from static to extern.

From-SVN: r234088
This commit is contained in:
David Malcolm 2016-03-09 18:23:27 +00:00 committed by David Malcolm
parent 40499f81a6
commit b4f3232d69
8 changed files with 199 additions and 4 deletions

View file

@ -1066,6 +1066,14 @@ int linemap_location_in_system_header_p (struct line_maps *,
bool linemap_location_from_macro_expansion_p (const struct line_maps *,
source_location);
/* With the precondition that LOCATION is the locus of a token that is
an argument of a function-like macro MACRO_MAP and appears in the
expansion of MACRO_MAP, return the locus of that argument in the
context of the caller of MACRO_MAP. */
extern source_location linemap_macro_map_loc_unwind_toward_spelling
(line_maps *set, const line_map_macro *macro_map, source_location location);
/* source_location values from 0 to RESERVED_LOCATION_COUNT-1 will
be reserved for libcpp user as special values, no token from libcpp
will contain any of those locations. */