Hi,

this is a regression present on the mainline, 10 and 9 branches introduced by 
a preparation patch for modules applied to libcpp a while ago by Nathan:

2018-10-31  Nathan Sidwell  <nat...@acm.org>

        * include/line-map.h (IS_ORDINARY_LOC, IS_MACRO_LOC): New
        predicates.
        (IS_ADHOC_LOC): Move earlier.
        (MAP_ORDINARY_P): Use IS_ORDINARY_LOC.
        * line-map.c (linemap_location_from_macro_expansion_p): Use
        IS_MACRO_LOC.

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:

  linemap_assert (line >= LINEMAPS_MACRO_LOWEST_LOCATION (set));

during GIMPLE pass: lower
in linemap_macro_map_lookup, at libcpp/line-map.c:1080during GIMPLE pass: 
lower
in linemap_macro_map_lookup, at libcpp/line-map.c:1080Internal compiler error: 
Error reporting routines re-entered.
0x210b2bf linemap_macro_map_lookup
        /home/eric/cvs/gcc/libcpp/line-map.c:1080
0x210b2bf linemap_lookup(line_maps const*, unsigned int)
        /home/eric/cvs/gcc/libcpp/line-map.c:1020
0x210b436 linemap_macro_loc_to_exp_point
        /home/eric/cvs/gcc/libcpp/line-map.c:1560
0x20e5b55 expand_location_1
        /home/eric/cvs/gcc/gcc/input.c:190
0x20e6f90 expand_location(unsigned int)
        /home/eric/cvs/gcc/gcc/input.c:809
0xb48119 internal_error_function
        /home/eric/cvs/gcc/gcc/ada/gcc-interface/misc.c:339
0x20c5108 diagnostic_report_diagnostic(diagnostic_context*, diagnostic_info*)
        /home/eric/cvs/gcc/gcc/diagnostic.c:1225
0x20c56ff diagnostic_impl
        /home/eric/cvs/gcc/gcc/diagnostic.c:1406
0x20c6087 internal_error(char const*, ...)
        /home/eric/cvs/gcc/gcc/diagnostic.c:1808
0xb1d217 fancy_abort(char const*, int, char const*)
        /home/eric/cvs/gcc/gcc/diagnostic.c:1907
0x210b2bf linemap_macro_map_lookup
        /home/eric/cvs/gcc/libcpp/line-map.c:1080
0x210b2bf linemap_lookup(line_maps const*, unsigned int)
        /home/eric/cvs/gcc/libcpp/line-map.c:1020
0x210b436 linemap_macro_loc_to_exp_point
        /home/eric/cvs/gcc/libcpp/line-map.c:1560
0x20e5b55 expand_location_1
        /home/eric/cvs/gcc/gcc/input.c:190
0x20e6f90 expand_location(unsigned int)
        /home/eric/cvs/gcc/gcc/input.c:809
0xb48119 internal_error_function
        /home/eric/cvs/gcc/gcc/ada/gcc-interface/misc.c:339
0x20c5108 diagnostic_report_diagnostic(diagnostic_context*, diagnostic_info*)
        /home/eric/cvs/gcc/gcc/diagnostic.c:1225
0x20c56ff diagnostic_impl
        /home/eric/cvs/gcc/gcc/diagnostic.c:1406
0x20c6087 internal_error(char const*, ...)
        /home/eric/cvs/gcc/gcc/diagnostic.c:1808
0xb1d217 fancy_abort(char const*, int, char const*)
        /home/eric/cvs/gcc/gcc/diagnostic.c:1907
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.

The attached fix simply deletes IS_MACRO_LOC and replaces it with the proper 
test, taking into account that IS_ADHOC_LOC has always already been tested.

Tested on x86-64/Linux, OK for mainline, 10 and 9 branches?


2021-03-23  Eric Botcazou  <ebotca...@adacore.com>

libcpp/
        * include/line-map.h (IS_MACRO_LOC): Delete.
        * line-map.c (linemap_location_from_macro_expansion_p): Test
        against the LINEMAPS_MACRO_LOWEST_LOCATION of the linemap.
gcc/cp/
        * module.cc (ordinary_loc_of): Likewise.
        (module_state::write_location): Likewise.

-- 
Eric Botcazou
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 6dbdc926cb4..f5f48e078ea 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -13774,7 +13774,7 @@ ordinary_loc_of (line_maps *lmaps, location_t from)
     {
       if (IS_ADHOC_LOC (from))
 	from = get_location_from_adhoc_loc (lmaps, from);
-      if (IS_MACRO_LOC (from))
+      if (from >= LINEMAPS_MACRO_LOWEST_LOCATION (lmaps))
 	{
 	  /* Find the ordinary location nearest FROM.  */
 	  const line_map *map = linemap_lookup (lmaps, from);
@@ -15608,7 +15608,7 @@ module_state::write_location (bytes_out &sec, location_t loc)
       write_location (sec, range.m_start);
       write_location (sec, range.m_finish);
     }
-  else if (IS_MACRO_LOC (loc))
+  else if (loc >= LINEMAPS_MACRO_LOWEST_LOCATION (line_table))
     {
       if (const loc_spans::span *span = spans.macro (loc))
 	{
diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h
index 40919d088ac..dcf404d3832 100644
--- a/libcpp/include/line-map.h
+++ b/libcpp/include/line-map.h
@@ -577,12 +577,6 @@ IS_ADHOC_LOC (location_t loc)
   return loc > MAX_LOCATION_T;
 }
 
-inline bool
-IS_MACRO_LOC (location_t loc)
-{
-  return !IS_ORDINARY_LOC (loc) && !IS_ADHOC_LOC (loc);
-}
-
 /* Categorize line map kinds.  */
 
 inline bool
diff --git a/libcpp/line-map.c b/libcpp/line-map.c
index a003af8533c..1bf0e8211f2 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

Reply via email to