libcpp: location comparison within macro [PR100796]

The patch for 96391 changed linemap_compare_locations to give up on
comparing locations from macro expansions if we don't have column
information.  But in this testcase, the BOILERPLATE macro is multiple lines
long, so we do want to compare locations within the macro.  So this patch
moves the LINE_MAP_MAX_LOCATION_WITH_COLS check inside the block, to use it
for failing gracefully.

	PR c++/100796
	PR preprocessor/96391

libcpp/ChangeLog:

	* line-map.c (linemap_compare_locations): Only use comparison with
	LINE_MAP_MAX_LOCATION_WITH_COLS to avoid abort.

gcc/testsuite/ChangeLog:

	* g++.dg/plugin/location-overflow-test-pr100796.c: New test.
	* g++.dg/plugin/plugin.exp: Run it.
This commit is contained in:
Jason Merrill 2021-06-14 17:37:43 -04:00
parent d92613ec55
commit bb2e908638
3 changed files with 38 additions and 10 deletions

View File

@ -0,0 +1,25 @@
// PR c++/100796
// { dg-additional-options "-Wsuggest-override -fplugin-arg-location_overflow_plugin-value=0x60000001" }
// Passing LINE_MAP_MAX_LOCATION_WITH_COLS meant we stopped distinguishing between lines in a macro.
#define DO_PRAGMA(text) _Pragma(#text)
#define WARNING_PUSH DO_PRAGMA(GCC diagnostic push)
#define WARNING_POP DO_PRAGMA(GCC diagnostic pop)
#define WARNING_DISABLE(text) DO_PRAGMA(GCC diagnostic ignored text)
#define NO_OVERRIDE_WARNING WARNING_DISABLE("-Wsuggest-override")
#define BOILERPLATE \
WARNING_PUSH \
NO_OVERRIDE_WARNING \
void f(); \
WARNING_POP
struct B
{
virtual void f();
};
struct D: B
{
BOILERPLATE
};

View File

@ -73,7 +73,8 @@ set plugin_test_list [list \
../../gcc.dg/plugin/diagnostic-test-string-literals-3.c \ ../../gcc.dg/plugin/diagnostic-test-string-literals-3.c \
../../gcc.dg/plugin/diagnostic-test-string-literals-4.c } \ ../../gcc.dg/plugin/diagnostic-test-string-literals-4.c } \
{ ../../gcc.dg/plugin/location_overflow_plugin.c \ { ../../gcc.dg/plugin/location_overflow_plugin.c \
location-overflow-test-pr96391.c } \ location-overflow-test-pr96391.c \
location-overflow-test-pr100796.c } \
{ show_template_tree_color_plugin.c \ { show_template_tree_color_plugin.c \
show-template-tree-color.C \ show-template-tree-color.C \
show-template-tree-color-labels.C \ show-template-tree-color-labels.C \

View File

@ -1421,24 +1421,26 @@ linemap_compare_locations (line_maps *set,
if (l0 == l1 if (l0 == l1
&& pre_virtual_p && pre_virtual_p
&& post_virtual_p && post_virtual_p)
&& l0 <= LINE_MAP_MAX_LOCATION_WITH_COLS)
{ {
/* So pre and post represent two tokens that are present in a /* So pre and post represent two tokens that are present in a
same macro expansion. Let's see if the token for pre was same macro expansion. Let's see if the token for pre was
before the token for post in that expansion. */ before the token for post in that expansion. */
unsigned i0, i1;
const struct line_map *map = const struct line_map *map =
first_map_in_common (set, pre, post, &l0, &l1); first_map_in_common (set, pre, post, &l0, &l1);
if (map == NULL) if (map == NULL)
/* This should not be possible. */ /* This should not be possible while we have column information, but if
abort (); we don't, the tokens could be from separate macro expansions on the
same line. */
i0 = l0 - MAP_START_LOCATION (map); gcc_assert (l0 > LINE_MAP_MAX_LOCATION_WITH_COLS);
i1 = l1 - MAP_START_LOCATION (map); else
{
unsigned i0 = l0 - MAP_START_LOCATION (map);
unsigned i1 = l1 - MAP_START_LOCATION (map);
return i1 - i0; return i1 - i0;
} }
}
if (IS_ADHOC_LOC (l0)) if (IS_ADHOC_LOC (l0))
l0 = get_location_from_adhoc_loc (set, l0); l0 = get_location_from_adhoc_loc (set, l0);