diff --git a/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-1.h b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-1.h new file mode 100644 index 000000000000..3dd6434a938b --- /dev/null +++ b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-1.h @@ -0,0 +1,6 @@ + + + + +#include "location-overflow-test-pr116047-2.h" +static_assert (__LINE__ == 6, ""); diff --git a/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-2.h b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-2.h new file mode 100644 index 000000000000..048f715b4656 --- /dev/null +++ b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047-2.h @@ -0,0 +1 @@ +int i; diff --git a/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047.c b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047.c new file mode 100644 index 000000000000..75161fa5f055 --- /dev/null +++ b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr116047.c @@ -0,0 +1,5 @@ +/* PR preprocessor/116047 */ +/* { dg-do preprocess } */ +/* { dg-options "-nostdinc -std=c23 -fplugin-arg-location_overflow_plugin-value=0x4ffe0180" } */ +#include "location-overflow-test-pr116047-1.h" +/* { dg-final { scan-file location-overflow-test-pr116047.i "static_assert\[^\n\r]\*6\[^\n\r]\*== 6" } } */ diff --git a/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-1.h b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-1.h new file mode 100644 index 000000000000..ebf7704f568e --- /dev/null +++ b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-1.h @@ -0,0 +1,6 @@ + + + + +#include "location-overflow-test-pr120061-2.h" + diff --git a/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-2.h b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-2.h new file mode 100644 index 000000000000..048f715b4656 --- /dev/null +++ b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061-2.h @@ -0,0 +1 @@ +int i; diff --git a/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061.c b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061.c new file mode 100644 index 000000000000..e8e803898da3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/plugin/location-overflow-test-pr120061.c @@ -0,0 +1,6 @@ +/* PR preprocessor/120061 */ +/* { dg-do preprocess } */ +/* { dg-options "-nostdinc -std=c23 -fplugin-arg-location_overflow_plugin-value=0x61000000" } */ +#include "location-overflow-test-pr120061-1.h" +static_assert (__LINE__ == 5, ""); +/* { dg-final { scan-file location-overflow-test-pr120061.i "static_assert\[^\n\r]\*5\[^\n\r]\*== 5" } } */ diff --git a/gcc/testsuite/gcc.dg/plugin/location_overflow_plugin.cc b/gcc/testsuite/gcc.dg/plugin/location_overflow_plugin.cc index f731b1421b0f..f770d35ea518 100644 --- a/gcc/testsuite/gcc.dg/plugin/location_overflow_plugin.cc +++ b/gcc/testsuite/gcc.dg/plugin/location_overflow_plugin.cc @@ -85,9 +85,18 @@ plugin_init (struct plugin_name_args *plugin_info, error_at (UNKNOWN_LOCATION, "missing plugin argument"); /* With 64-bit locations, the thresholds are larger, so shift the base - location argument accordingly. */ + location argument accordingly, basically remap the GCC 14 32-bit + location_t argument values to 64-bit location_t counterparts. There + is one exception for values slightly before the 32-bit location_t + LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES (0x50000000). In that case + remap them to the same amount before the 64-bit location_t + LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES - + ((location_t) 0x50000000) << 31. */ gcc_assert (sizeof (location_t) == sizeof (uint64_t)); - base_location = 1 + ((base_location - 1) << 31); + if (base_location >= 0x4f000000 && base_location <= 0x4fffffff) + base_location += (((location_t) 0x50000000) << 31) - 0x50000000; + else + base_location = 1 + ((base_location - 1) << 31); register_callback (plugin_info->base_name, PLUGIN_PRAGMAS, @@ -107,7 +116,7 @@ plugin_init (struct plugin_name_args *plugin_info, break; default: - error_at (UNKNOWN_LOCATION, "unrecognized value for plugin argument"); + break; } return 0; diff --git a/gcc/testsuite/gcc.dg/plugin/plugin.exp b/gcc/testsuite/gcc.dg/plugin/plugin.exp index 90c91621d0aa..96e76d2e0c36 100644 --- a/gcc/testsuite/gcc.dg/plugin/plugin.exp +++ b/gcc/testsuite/gcc.dg/plugin/plugin.exp @@ -138,7 +138,9 @@ set plugin_test_list [list \ { location_overflow_plugin.cc \ location-overflow-test-1.c \ location-overflow-test-2.c \ - location-overflow-test-pr83173.c } \ + location-overflow-test-pr83173.c \ + location-overflow-test-pr116047.c \ + location-overflow-test-pr120061.c } \ { must_tail_call_plugin.cc \ must-tail-call-1.c \ must-tail-call-2.c } \ diff --git a/libcpp/files.cc b/libcpp/files.cc index c1abde6639fe..d80c4bfd9077 100644 --- a/libcpp/files.cc +++ b/libcpp/files.cc @@ -1047,14 +1047,6 @@ _cpp_stack_file (cpp_reader *pfile, _cpp_file *file, include_type type, && (pfile->line_table->highest_location != LINE_MAP_MAX_LOCATION - 1)); - if (decrement && LINEMAPS_ORDINARY_USED (pfile->line_table)) - { - const line_map_ordinary *map - = LINEMAPS_LAST_ORDINARY_MAP (pfile->line_table); - if (map && map->start_location == pfile->line_table->highest_location) - decrement = false; - } - if (decrement) pfile->line_table->highest_location--; diff --git a/libcpp/line-map.cc b/libcpp/line-map.cc index 17e7f12551c0..cf6557117c81 100644 --- a/libcpp/line-map.cc +++ b/libcpp/line-map.cc @@ -621,8 +621,8 @@ linemap_add (line_maps *set, enum lc_reason reason, #include "included", inside the same "includer" file. */ linemap_assert (!MAIN_FILE_P (map - 1)); - /* (MAP - 1) points to the map we are leaving. The - map from which (MAP - 1) got included should be the map + /* (MAP - 1) points to the map we are leaving. The + map from which (MAP - 1) got included should be usually the map that comes right before MAP in the same file. */ from = linemap_included_from_linemap (set, map - 1); @@ -630,7 +630,24 @@ linemap_add (line_maps *set, enum lc_reason reason, if (to_file == NULL) { to_file = ORDINARY_MAP_FILE_NAME (from); - to_line = SOURCE_LINE (from, from[1].start_location); + /* Compute the line on which the map resumes, for #include this + should be the line after the #include line. Usually FROM is + the map right before LC_ENTER map - the first map of the included + file, and in that case SOURCE_LINE (from, from[1].start_location); + computes the right line (and does handle even some special cases + (e.g. where for returning from we still want to + be at line 0 or some -traditional-cpp cases). In rare cases + FROM can be followed by LC_RENAME created by linemap_line_start + for line right after #include line. If that happens, + start_location of the FROM[1] map will be the same as + start_location of FROM[2] LC_ENTER, but FROM[1] start_location + might not have advance enough for moving to a full next line. + In that case compute the line of #include line and add 1 to it + to advance to the next line. See PR120061. */ + if (from[1].reason == LC_RENAME) + to_line = SOURCE_LINE (from, linemap_included_from (map - 1)) + 1; + else + to_line = SOURCE_LINE (from, from[1].start_location); sysp = ORDINARY_MAP_IN_SYSTEM_HEADER_P (from); } else @@ -660,11 +677,26 @@ linemap_add (line_maps *set, enum lc_reason reason, if (set->depth == 0) map->included_from = 0; else - /* The location of the end of the just-closed map. */ - map->included_from - = (((map[0].start_location - 1 - map[-1].start_location) - & ~((loc_one << map[-1].m_column_and_range_bits) - 1)) - + map[-1].start_location); + { + /* Compute location from whence this line map was included. + For #include this should be preferrably column 0 of the + line on which #include directive appears. + map[-1] is the just closed map and usually included_from + falls within that map. In rare cases linemap_line_start + can insert a new LC_RENAME map for the line immediately + after #include line, in that case map[-1] will have the + same start_location as the new one and so included_from + would not be from map[-1] but likely map[-2]. If that + happens, mask off map[-2] m_column_and_range_bits bits + instead of map[-1]. See PR120061. */ + int i = -1; + while (map[i].start_location == map[0].start_location) + --i; + map->included_from + = (((map[0].start_location - 1 - map[i].start_location) + & ~((loc_one << map[i].m_column_and_range_bits) - 1)) + + map[i].start_location); + } set->depth++; if (set->trace_includes) trace_include (set, map);