https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105608
--- Comment #2 from Lewis Hyatt <lhyatt at gcc dot gnu.org> --- When a PCH file is restored, the global line_maps instance is replaced with the one that was stored in the PCH file. Hence any locations that were generated prior to restoring the PCH file need to be added back to it. Currently, the only such locations that can arise will be from preprocessor directives, such as #define. The save/restore process is handled by libcpp/pch.cc and, looking over this now, it doesn't seem it makes any effort to assign valid locations when re-adding the saved macros. If the just-restored line map is at depth=0, as it is after processing the empty pch, then it produces the ICE noted here in case the first line map added is of type LC_RENAME, which happens if an ad-hoc location is needed due to the long line. However you can see the invalid locations without an ICE as well, for instance in this simpler example: $ echo -n > h.h $ cat > a.cpp #define HELLO #include "h.h" $ gcc -x c++-header -c h.h $ gcc -x c++ -c a.cpp -Wunused-macros h.h:2: warning: macro "HELLO" is not used [-Wunused-macros] Note that the warning is emitted with the wrong filename and the wrong line number. If the PCH is absent, it will be correct, but when the definition of HELLO is processed the second time after PCH restore, it comes out wrong. Fixing this issue will also fix the ICE reported here; I think it will be needed to add some more infrastructure in libcpp/pch.cc so that it can add to the line map with proper locations. I can look into it sometime. This was always incorrect AFAIK, and did not regress with r11-338-g2a0225e47868fbfc specifically; that commit did make the line number change from 1 to 2, because it handles EOF differently, and I think that caused Sergei's test case to ICE rather than be silently wrong. BTW, the issue can also be papered over by moving these 2 lines: ==== diff --git a/gcc/c-family/c-pch.cc b/gcc/c-family/c-pch.cc index 2f014fca210..9ee6f179002 100644 --- a/gcc/c-family/c-pch.cc +++ b/gcc/c-family/c-pch.cc @@ -342,6 +342,8 @@ c_common_read_pch (cpp_reader *pfile, const char *name, gt_pch_restore (f); cpp_set_line_map (pfile, line_table); rebuild_location_adhoc_htab (line_table); + line_table->trace_includes = saved_trace_includes; + linemap_add (line_table, LC_ENTER, 0, saved_loc.file, saved_loc.line); timevar_push (TV_PCH_CPP_RESTORE); if (cpp_read_state (pfile, name, f, smd) != 0) @@ -355,9 +357,6 @@ c_common_read_pch (cpp_reader *pfile, const char *name, fclose (f); - line_table->trace_includes = saved_trace_includes; - linemap_add (line_table, LC_ENTER, 0, saved_loc.file, saved_loc.line); - /* Give the front end a chance to take action after a PCH file has been loaded. */ if (lang_post_pch_load) ===== With that change, you still get wrong locations for the restored macros, but the line_map state is sufficiently improved that the ICE is avoided. (The locations get assigned, as if all the macros were defined on the line following the PCH include.)