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.)

Reply via email to