]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[c-family] Backport fix for PCH / PR61250.
authorIain Sandoe <iain@sandoe.co.uk>
Thu, 5 Sep 2019 19:27:31 +0000 (19:27 +0000)
committerIain Sandoe <iains@gcc.gnu.org>
Thu, 5 Sep 2019 19:27:31 +0000 (19:27 +0000)
When we are parsing a source file, the very first token might
be a PRAGMA_GCC_PCH_PREPROCESS. This indicates that we are going
read in a PCH file (named as the value of the pragma). If we don't
see this pragma, then we know that it's OK to release any resources
that the host might have set aside for the PCH file.

There is a thinko in the current implementation, in that the decision
to release resources is happening unconditionally right after the first
token is extracted but before it's been checked or acted upon.

This leads to the pch bug on Darwin, because we actually do release
resources - which are subsequently (reasonably) assumed to be available
when reading a PCH file. We then get random crashes or hangs depending
on the interaction between unmmap and malloc.

The bug is present everywhere but doesn't show on (say) Linux, since
the release of PCH resources is a NOP there.

This effects all the c-family front ends, because they all use
c_lex_with_flags () to implement this.

The solution is to check for the PRAGMA_GCC_PCH_PREPROCESS and only call
c_common_no_more_pch () when that is not the first token.

A secondary effect of the collection is that the name of the PCH file
can be collected during the ggc_pch_read() reset of state. Therefore
we should issue any diagnostic that might name the file before the
collections are triggered.

gcc/

2019-09-05  Iain Sandoe  <iain@sandoe.co.uk>

Backport from mainline
2019-08-23  Iain Sandoe  <iain@sandoe.co.uk>

PR pch/61250
* ggc-page.c (ggc_pch_read): Read the ggc_pch_ondisk structure
and issue any diagnostics needed before collecting the pre-PCH
state.

gcc/c-family/

2019-09-05  Iain Sandoe  <iain@sandoe.co.uk>

Backport from mainline
2019-08-23  Iain Sandoe  <iain@sandoe.co.uk>

PR pch/61250
* c-lex.c (c_lex_with_flags):  Don't call
c_common_no_more_pch () from here.

gcc/c

2019-09-05  Iain Sandoe  <iain@sandoe.co.uk>

Backport from mainline.
2019-08-23  Iain Sandoe  <iain@sandoe.co.uk>

PR pch/61250
* c-parser.c (c_parse_file): Call c_common_no_more_pch ()
after determining that the first token is not
PRAGMA_GCC_PCH_PREPROCESS.

gcc/cp/

2019-09-05  Iain Sandoe  <iain@sandoe.co.uk>

Backported from mainline
2019-08-23  Iain Sandoe  <iain@sandoe.co.uk>

PR pch/61250
* parser.c (cp_parser_initial_pragma): Call c_common_no_more_pch ()
after determining that the first token is not
PRAGMA_GCC_PCH_PREPROCESS.

From-SVN: r275431

gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c-lex.c
gcc/c/ChangeLog
gcc/c/c-parser.c
gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/ggc-page.c

index 308c44b8cc99ba9bc1803821b2ea790a2d7279b3..b11534d410a36c95a4491e654c7be41676639b6b 100644 (file)
@@ -1,3 +1,13 @@
+2019-09-05  Iain Sandoe  <iain@sandoe.co.uk>
+
+       Backport from mainline
+       2019-08-23  Iain Sandoe  <iain@sandoe.co.uk>
+
+       PR pch/61250
+       * ggc-page.c (ggc_pch_read): Read the ggc_pch_ondisk structure
+       and issue any diagnostics needed before collecting the pre-PCH
+       state.
+
 2019-09-05  Iain Sandoe  <iain@sandoe.co.uk>
 
        Backport from mainline
index 8c77a6ab9007dd344a4226bbdc0c22d37523d1c4..f42239755a8e7edc99a534a9682c73bb12537fae 100644 (file)
@@ -1,3 +1,12 @@
+2019-09-05  Iain Sandoe  <iain@sandoe.co.uk>
+
+       Backport from mainline
+       2019-08-23  Iain Sandoe  <iain@sandoe.co.uk>
+
+       PR pch/61250
+       * c-lex.c (c_lex_with_flags):  Don't call
+       c_common_no_more_pch () from here.
+
 2019-08-30  Richard Biener  <rguenther@suse.de>
 
        Backport from mainline
index e1c8bdff98687d37d490cc11ba450f5b6e70e9cb..46a2f449eca3eed38a220ac69113e932799338f1 100644 (file)
@@ -387,7 +387,6 @@ enum cpp_ttype
 c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags,
                  int lex_flags)
 {
-  static bool no_more_pch;
   const cpp_token *tok;
   enum cpp_ttype type;
   unsigned char add_flags = 0;
@@ -621,12 +620,6 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags,
   if (cpp_flags)
     *cpp_flags = tok->flags | add_flags;
 
-  if (!no_more_pch)
-    {
-      no_more_pch = true;
-      c_common_no_more_pch ();
-    }
-
   timevar_pop (TV_CPP);
 
   return type;
index 394457213f78651f0afb21098ceced2682fd7984..d7c5573ac810d74aecea473bfaeda2fc094f3d26 100644 (file)
@@ -1,3 +1,13 @@
+2019-09-05  Iain Sandoe  <iain@sandoe.co.uk>
+
+       Backport from mainline.
+       2019-08-23  Iain Sandoe  <iain@sandoe.co.uk>
+
+       PR pch/61250
+       * c-parser.c (c_parse_file): Call c_common_no_more_pch ()
+       after determining that the first token is not
+       PRAGMA_GCC_PCH_PREPROCESS.
+
 2019-08-30  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
index 86195c53249ef4937b647644bfd6d698824daf12..339b9a0cda18d8499c775cb4c05bedb706aa9d84 100644 (file)
@@ -18214,6 +18214,8 @@ c_parse_file (void)
 
   if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS)
     c_parser_pragma_pch_preprocess (&tparser);
+  else
+    c_common_no_more_pch ();
 
   the_parser = ggc_alloc<c_parser> ();
   *the_parser = tparser;
index e84b9a2ff7440b874d93592f35f6d2099cff4cc7..3ffcd011b106b615e02fede682a73cede2fa6963 100644 (file)
@@ -1,3 +1,13 @@
+2019-09-05  Iain Sandoe  <iain@sandoe.co.uk>
+
+       Backported from mainline
+       2019-08-23  Iain Sandoe  <iain@sandoe.co.uk>
+
+       PR pch/61250
+       * parser.c (cp_parser_initial_pragma): Call c_common_no_more_pch ()
+       after determining that the first token is not
+       PRAGMA_GCC_PCH_PREPROCESS.
+
 2019-09-02  Richard Biener  <rguenther@suse.de>
 
        Backport from mainline
index 7542a96dcac5ab257c2a943d11092655e9ea4c97..073fe434b93d6d3c1da9dbcdd023f9d0cd3bf171 100644 (file)
@@ -38232,7 +38232,10 @@ cp_parser_initial_pragma (cp_token *first_token)
 
   cp_lexer_get_preprocessor_token (NULL, first_token);
   if (cp_parser_pragma_kind (first_token) != PRAGMA_GCC_PCH_PREPROCESS)
-    return;
+    {
+      c_common_no_more_pch ();
+      return;
+    }
 
   cp_lexer_get_preprocessor_token (NULL, first_token);
   if (first_token->type == CPP_STRING)
index da994c2faea3ba9aadc9d0c3cd8a3e253a47e75a..4281fe6ebf9bc581fec320e667e48ce590f17f66 100644 (file)
@@ -2553,6 +2553,9 @@ ggc_pch_read (FILE *f, void *addr)
 
   count_old_page_tables = G.by_depth_in_use;
 
+  if (fread (&d, sizeof (d), 1, f) != 1)
+    fatal_error (input_location, "cannot read PCH file: %m");
+
   /* We've just read in a PCH file.  So, every object that used to be
      allocated is now free.  */
   clear_marks ();
@@ -2581,8 +2584,6 @@ ggc_pch_read (FILE *f, void *addr)
 
   /* Allocate the appropriate page-table entries for the pages read from
      the PCH file.  */
-  if (fread (&d, sizeof (d), 1, f) != 1)
-    fatal_error (input_location, "can%'t read PCH file: %m");
 
   for (i = 0; i < NUM_ORDERS; i++)
     {