From 1174314811af52779497462f26d21ea0038d1a85 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Tue, 13 Apr 2021 11:57:55 +0200 Subject: Fix thinko in libcpp preparation patch for modules The problem is that the new IS_MACRO_LOC macro: inline bool IS_MACRO_LOC (location_t loc) { return !IS_ORDINARY_LOC (loc) && !IS_ADHOC_LOC (loc); } is not fully correct since the position of the macro lines is not fixed: /* Returns the lowest location [of a token resulting from macro expansion] encoded in this line table. */ inline location_t LINEMAPS_MACRO_LOWEST_LOCATION (const line_maps *set) { return LINEMAPS_MACRO_USED (set) ? MAP_START_LOCATION (LINEMAPS_LAST_MACRO_MAP (set)) : MAX_LOCATION_T + 1; } In Ada, LINEMAPS_MACRO_USED is false so LINEMAPS_MACRO_LOWEST_LOCATION is MAX_LOCATION_T + 1, but IS_MACRO_LOC nevertheless returns true for anything in the range [LINE_MAP_MAX_LOCATION; MAX_LOCATION_T], thus yielding an ICE in linemap_macro_map_lookup for very large files. libcpp/ * include/line-map.h (IS_MACRO_LOC): Delete. * line-map.c (linemap_location_from_macro_expansion_p): Test LINEMAPS_MACRO_LOWEST_LOCATION of the linemap. gcc/cp/ * module.cc (ordinary_loc_of): Test LINEMAPS_MACRO_LOWEST_LOCATION of the linemap. (module_state::write_location): Likewise. --- libcpp/line-map.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libcpp/line-map.c') diff --git a/libcpp/line-map.c b/libcpp/line-map.c index a003af8..1bf0e82 100644 --- a/libcpp/line-map.c +++ b/libcpp/line-map.c @@ -1321,7 +1321,7 @@ linemap_location_from_macro_expansion_p (const class line_maps *set, if (IS_ADHOC_LOC (location)) location = get_location_from_adhoc_loc (set, location); - return IS_MACRO_LOC (location); + return location >= LINEMAPS_MACRO_LOWEST_LOCATION (set); } /* Given two virtual locations *LOC0 and *LOC1, return the first -- cgit v1.1 From 4acb3af3669db4ca79ffc97cd615fcea205bcccb Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Tue, 13 Apr 2021 05:03:19 -0700 Subject: preprocessor: Fix column adjustment [PR 99446] This ICE was because when adjusting a column offset we could advance into a linemap for a different file. We only checked the next line map was not for a line further advanced in any file, forgetting that it could be for an earlier line in a different file. The testcase needed adjusting as column 512 was unrepresentable, once that was taken into consideration. PR preprocessor/99446 libcpp/ * line-map.c (line-map.c): Do not advance to linemaps for different files. gcc/testsuite/ * g++.dg/diagnostic/pr72803.C: Adjust expected column. --- libcpp/line-map.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'libcpp/line-map.c') diff --git a/libcpp/line-map.c b/libcpp/line-map.c index 1bf0e82..2f5e444 100644 --- a/libcpp/line-map.c +++ b/libcpp/line-map.c @@ -981,16 +981,15 @@ linemap_position_for_loc_and_offset (line_maps *set, (loc + offset) should be less than the first location encoded by the next line map of the set. Otherwise, we try to encode the location in the next map. */ - while (map != LINEMAPS_LAST_ORDINARY_MAP (set) - && (loc + (column_offset << map->m_range_bits) - >= MAP_START_LOCATION (&map[1]))) - { - map = &map[1]; - /* If the next map starts in a higher line, we cannot encode the - location there. */ - if (line < ORDINARY_MAP_STARTING_LINE_NUMBER (map)) - return loc; - } + for (; map != LINEMAPS_LAST_ORDINARY_MAP (set) + && (loc + (column << map->m_range_bits) + >= MAP_START_LOCATION (map + 1)); map++) + /* If the next map is a different file, or starts in a higher line, we + cannot encode the location there. */ + if ((map + 1)->reason != LC_RENAME + || line < ORDINARY_MAP_STARTING_LINE_NUMBER (map + 1) + || 0 != strcmp (LINEMAP_FILE (map + 1), LINEMAP_FILE (map))) + return loc; column += column_offset; -- cgit v1.1 From 2f422b550ff6351d312e6c81a00b488d9280bfff Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 19 Apr 2021 10:07:35 +0200 Subject: preprocessor/100142 - revert unwanted change in last commit This reverts a s/column_offset/column/ change in the fix for PR99446. 2021-04-19 Richard Biener PR preprocessor/100142 libcpp/ * line-map.c (linemap_position_for_loc_and_offset): Revert unintended s/column_offset/column/ change. gcc/testsuite/ * gcc.dg/pr100142.c: New testcase. * g++.dg/diagnostic/pr72803.C: Revert last change. --- libcpp/line-map.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libcpp/line-map.c') diff --git a/libcpp/line-map.c b/libcpp/line-map.c index 2f5e444..a03d676 100644 --- a/libcpp/line-map.c +++ b/libcpp/line-map.c @@ -982,7 +982,7 @@ linemap_position_for_loc_and_offset (line_maps *set, the next line map of the set. Otherwise, we try to encode the location in the next map. */ for (; map != LINEMAPS_LAST_ORDINARY_MAP (set) - && (loc + (column << map->m_range_bits) + && (loc + (column_offset << map->m_range_bits) >= MAP_START_LOCATION (map + 1)); map++) /* If the next map is a different file, or starts in a higher line, we cannot encode the location there. */ -- cgit v1.1 From 9e64426dae129cca5b62355ef6c5a3bd6137e830 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 14 Jun 2021 17:37:43 -0400 Subject: 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. --- libcpp/line-map.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'libcpp/line-map.c') diff --git a/libcpp/line-map.c b/libcpp/line-map.c index a03d676..1a6902a 100644 --- a/libcpp/line-map.c +++ b/libcpp/line-map.c @@ -1421,23 +1421,25 @@ linemap_compare_locations (line_maps *set, if (l0 == l1 && pre_virtual_p - && post_virtual_p - && l0 <= LINE_MAP_MAX_LOCATION_WITH_COLS) + && post_virtual_p) { /* So pre and post represent two tokens that are present in a same macro expansion. Let's see if the token for pre was before the token for post in that expansion. */ - unsigned i0, i1; const struct line_map *map = first_map_in_common (set, pre, post, &l0, &l1); if (map == NULL) - /* This should not be possible. */ - abort (); - - i0 = l0 - MAP_START_LOCATION (map); - i1 = l1 - MAP_START_LOCATION (map); - return i1 - i0; + /* This should not be possible while we have column information, but if + we don't, the tokens could be from separate macro expansions on the + same line. */ + gcc_assert (l0 > LINE_MAP_MAX_LOCATION_WITH_COLS); + else + { + unsigned i0 = l0 - MAP_START_LOCATION (map); + unsigned i1 = l1 - MAP_START_LOCATION (map); + return i1 - i0; + } } if (IS_ADHOC_LOC (l0)) -- cgit v1.1