From 7a525d23aad8bf2f4db37f384c331af1abf7f103 Mon Sep 17 00:00:00 2001 From: Lewis Hyatt Date: Tue, 5 Dec 2023 11:33:39 -0500 Subject: [PATCH] c-family: Fix ICE with large column number after restoring a PCH [PR105608] Users are allowed to define macros prior to restoring a precompiled header file, as long as those macros are not defined (or are defined identically) in the PCH. However, the PCH restoration process destroys all the macro definitions, so libcpp has to record them before restoring the PCH and then redefine them afterward. This process does not currently assign great locations to the macros after redefining them. Some work is needed to also remember the original locations and get the line_maps instance in the right state (since, like all other data structures, the line_maps instance is also reset after restoring a PCH). This patch addresses a more pressing issue, which is that we ICE in some cases since GCC 11, hitting an assert in line-maps.cc. It happens if the first line encountered after the PCH restore requires an LC_RENAME map, such as will happen if the line is sufficiently long. This is much easier to fix, since we just need to call linemap_line_start before asking libcpp to redefine the stored macros, instead of afterward, to avoid the unexpected need for an LC_RENAME before an LC_ENTER has been seen. gcc/c-family/ChangeLog: PR preprocessor/105608 * c-pch.c (c_common_read_pch): Start a new line map before asking libcpp to restore macros defined prior to reading the PCH, instead of afterward. gcc/testsuite/ChangeLog: PR preprocessor/105608 * g++.dg/pch/line-map-1.C: New test. * g++.dg/pch/line-map-1.Hs: New test. * g++.dg/pch/line-map-2.C: New test. * g++.dg/pch/line-map-2.Hs: New test. --- gcc/c-family/c-pch.c | 5 ++--- gcc/testsuite/g++.dg/pch/line-map-1.C | 4 ++++ gcc/testsuite/g++.dg/pch/line-map-1.Hs | 1 + gcc/testsuite/g++.dg/pch/line-map-2.C | 6 ++++++ gcc/testsuite/g++.dg/pch/line-map-2.Hs | 1 + gcc/testsuite/g++.dg/pch/line-map-3.Hs | 1 + 6 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/pch/line-map-1.C create mode 100644 gcc/testsuite/g++.dg/pch/line-map-1.Hs create mode 100644 gcc/testsuite/g++.dg/pch/line-map-2.C create mode 100644 gcc/testsuite/g++.dg/pch/line-map-2.Hs create mode 100644 gcc/testsuite/g++.dg/pch/line-map-3.Hs diff --git a/gcc/c-family/c-pch.c b/gcc/c-family/c-pch.c index fd94c3799aca..de72859d943b 100644 --- a/gcc/c-family/c-pch.c +++ b/gcc/c-family/c-pch.c @@ -354,6 +354,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) @@ -367,9 +369,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) diff --git a/gcc/testsuite/g++.dg/pch/line-map-1.C b/gcc/testsuite/g++.dg/pch/line-map-1.C new file mode 100644 index 000000000000..9d1ac6d1683a --- /dev/null +++ b/gcc/testsuite/g++.dg/pch/line-map-1.C @@ -0,0 +1,4 @@ +/* PR preprocessor/105608 */ +/* { dg-do compile } */ +#define MACRO_ON_A_LONG_LINE "this line is long enough that it forces the line table to create an LC_RENAME map, which formerly triggered an ICE after PCH restore" +#include "line-map-1.H" diff --git a/gcc/testsuite/g++.dg/pch/line-map-1.Hs b/gcc/testsuite/g++.dg/pch/line-map-1.Hs new file mode 100644 index 000000000000..3b6178bfae0f --- /dev/null +++ b/gcc/testsuite/g++.dg/pch/line-map-1.Hs @@ -0,0 +1 @@ +/* This space intentionally left blank. */ diff --git a/gcc/testsuite/g++.dg/pch/line-map-2.C b/gcc/testsuite/g++.dg/pch/line-map-2.C new file mode 100644 index 000000000000..0be035781c83 --- /dev/null +++ b/gcc/testsuite/g++.dg/pch/line-map-2.C @@ -0,0 +1,6 @@ +/* PR preprocessor/105608 */ +/* { dg-do compile } */ +/* { dg-additional-options "-save-temps" } */ +#define MACRO_ON_A_LONG_LINE "this line is long enough that it forces the line table to create an LC_RENAME map, which formerly triggered an ICE after PCH restore" +#include "line-map-2.H" +#error "suppress PCH assembly comparison, which does not work with -save-temps" /* { dg-error "." } */ diff --git a/gcc/testsuite/g++.dg/pch/line-map-2.Hs b/gcc/testsuite/g++.dg/pch/line-map-2.Hs new file mode 100644 index 000000000000..3b6178bfae0f --- /dev/null +++ b/gcc/testsuite/g++.dg/pch/line-map-2.Hs @@ -0,0 +1 @@ +/* This space intentionally left blank. */ diff --git a/gcc/testsuite/g++.dg/pch/line-map-3.Hs b/gcc/testsuite/g++.dg/pch/line-map-3.Hs new file mode 100644 index 000000000000..3b6178bfae0f --- /dev/null +++ b/gcc/testsuite/g++.dg/pch/line-map-3.Hs @@ -0,0 +1 @@ +/* This space intentionally left blank. */ -- 2.47.2