This patch fixes a segmentation fault during function expansion
by delaying all expansions to happen after the PPH file has been
read.

The patch fixes one test (x1template.cc), but it exposes a common
ICE in resume_scope in other two tests.  Lawrence, this is the
ICE that you are now looking at, I think.  Your patch should fix
these two cases now.

Tested on x86_64.  Committed to the branch.

        * pph-streamer-in.c (pph_read_file_contents): Call
        expand_or_defer_fn on every function in stream->fns_to_expand.
        (pph_in_function_decl): If FNDECL has a body, add it to
        stream->fns_to_expand.
        (pph_read_tree): Tidy argument list.
        * pph-streamer.h (struct pph_stream): Add field fns_to_expand.

testsuite/ChangeLog.pph

        * g++.dg/pph/x1dynarray1.cc: Adjust xfail.
        * g++.dg/pph/x1namespace.cc: Likewise.
        * g++.dg/pph/x1template.cc: Mark fixed.

diff --git a/gcc/cp/ChangeLog.pph b/gcc/cp/ChangeLog.pph
index 9465484..eaf7121 100644
--- a/gcc/cp/ChangeLog.pph
+++ b/gcc/cp/ChangeLog.pph
@@ -1,4 +1,13 @@
 2011-06-29   Diego Novillo  <dnovi...@google.com>
+
+       * pph-streamer-in.c (pph_read_file_contents): Call
+       expand_or_defer_fn on every function in stream->fns_to_expand.
+       (pph_in_function_decl): If FNDECL has a body, add it to
+       stream->fns_to_expand.
+       (pph_read_tree): Tidy argument list.
+       * pph-streamer.h (struct pph_stream): Add field fns_to_expand.
+
+2011-06-29   Diego Novillo  <dnovi...@google.com>
             Lawrence Crowl  <cr...@google.com>
 
        * pph-streamer-in.c (pph_in_lang_specific): Expect shared
diff --git a/gcc/cp/pph-streamer-in.c b/gcc/cp/pph-streamer-in.c
index 1c71c30..3ac5243 100644
--- a/gcc/cp/pph-streamer-in.c
+++ b/gcc/cp/pph-streamer-in.c
@@ -1311,6 +1311,8 @@ pph_read_file_contents (pph_stream *stream)
   cpp_ident_use *bad_use;
   const char *cur_def;
   cpp_idents_used idents_used;
+  tree fndecl;
+  unsigned i;
 
   pph_in_identifiers (stream, &idents_used);
 
@@ -1333,6 +1335,23 @@ pph_read_file_contents (pph_stream *stream)
   /* FIXME pph: This call replaces the tinfo, we should merge instead.
      See pph_in_tree_vec.  */
   unemitted_tinfo_decls = pph_in_tree_vec (stream);
+
+  /* Expand all the functions with bodies that we read from STREAM.  */
+  for (i = 0; VEC_iterate (tree, stream->fns_to_expand, i, fndecl); i++)
+    {
+      /* FIXME pph - This is somewhat gross.  When we generated the
+        PPH image, the parser called expand_or_defer_fn on FNDECL,
+        which marked it DECL_EXTERNAL (see expand_or_defer_fn_1 for
+        details).
+
+        However, this is not really an extern definition, so it was
+        also marked not-really-extern (yes, I know...). If this
+        happens, we need to unmark it, otherwise the code generator
+        will toss it out.  */
+      if (DECL_NOT_REALLY_EXTERN (fndecl))
+       DECL_EXTERNAL (fndecl) = 0;
+      expand_or_defer_fn (fndecl);
+    }
 }
 
 
@@ -1372,20 +1391,7 @@ pph_in_function_decl (pph_stream *stream, tree fndecl)
   DECL_STRUCT_FUNCTION (fndecl) = pph_in_struct_function (stream, fndecl);
   DECL_CHAIN (fndecl) = pph_in_tree (stream);
   if (DECL_SAVED_TREE (fndecl))
-    {
-      /* FIXME pph - This is somewhat gross.  When we generated the
-        PPH image, the parser called expand_or_defer_fn on FNDECL,
-        which marked it DECL_EXTERNAL (see expand_or_defer_fn_1 for
-        details).
-
-        However, this is not really an extern definition, so it was
-        also marked not-really-extern (yes, I know...). If this
-        happens, we need to unmark it, otherwise the code generator
-        will toss it out.  */
-      if (DECL_NOT_REALLY_EXTERN (fndecl))
-       DECL_EXTERNAL (fndecl) = 0;
-      expand_or_defer_fn (fndecl);
-    }
+    VEC_safe_push (tree, gc, stream->fns_to_expand, fndecl);
 }
 
 
@@ -1396,7 +1402,7 @@ pph_in_function_decl (pph_stream *stream, tree fndecl)
 
 void
 pph_read_tree (struct lto_input_block *ib ATTRIBUTE_UNUSED,
-                     struct data_in *data_in, tree expr)
+              struct data_in *data_in, tree expr)
 {
   pph_stream *stream = (pph_stream *) data_in->sdata;
 
diff --git a/gcc/cp/pph-streamer.h b/gcc/cp/pph-streamer.h
index b36d622..b899501 100644
--- a/gcc/cp/pph-streamer.h
+++ b/gcc/cp/pph-streamer.h
@@ -116,6 +116,10 @@ typedef struct pph_stream {
 
   /* Nonzero if the stream was opened for writing.  */
   unsigned int write_p : 1;
+
+  /* List of functions with bodies that need to be expanded after
+     reading the PPH file.  */
+  VEC(tree,gc) *fns_to_expand;
 } pph_stream;
 
 /* Filter values for pph_out_chain_filtered.  */
diff --git a/gcc/testsuite/ChangeLog.pph b/gcc/testsuite/ChangeLog.pph
index aeede51..c5e1634 100644
--- a/gcc/testsuite/ChangeLog.pph
+++ b/gcc/testsuite/ChangeLog.pph
@@ -1,5 +1,11 @@
 2011-06-29  Diego Novillo  <dnovi...@google.com>
 
+       * g++.dg/pph/x1dynarray1.cc: Adjust xfail.
+       * g++.dg/pph/x1namespace.cc: Likewise.
+       * g++.dg/pph/x1template.cc: Mark fixed.
+
+2011-06-29  Diego Novillo  <dnovi...@google.com>
+
        * g++.dg/pph/c1attr-warn-unused-result.cc: Remove xfail marker.
 
 2011-06-28  Diego Novillo  <dnovi...@google.com>
diff --git a/gcc/testsuite/g++.dg/pph/x1dynarray1.cc 
b/gcc/testsuite/g++.dg/pph/x1dynarray1.cc
index 19f5b4c..527eace 100644
--- a/gcc/testsuite/g++.dg/pph/x1dynarray1.cc
+++ b/gcc/testsuite/g++.dg/pph/x1dynarray1.cc
@@ -1,5 +1,8 @@
 // { dg-xfail-if "ICE" { "*-*-*" } { "-fpph-map=pph.map" } }
-// { dg-bogus "internal compiler error: Segmentation fault" "" { xfail *-*-* } 
0 }
+// { dg-bogus "internal compiler error: in resume_scope" "" { xfail *-*-* } 0 }
+// { dg-bogus "from .*" "" { xfail *-*-* } 0 }
+// { dg-bogus "fails macro validation " "" { xfail *-*-* } 0 }
+// { dg-prune-output "In file included from " }
 
 #include "x1dynarray1.h"
 #include <iostream>
diff --git a/gcc/testsuite/g++.dg/pph/x1namespace.cc 
b/gcc/testsuite/g++.dg/pph/x1namespace.cc
index 16afff9..92cd248 100644
--- a/gcc/testsuite/g++.dg/pph/x1namespace.cc
+++ b/gcc/testsuite/g++.dg/pph/x1namespace.cc
@@ -1,5 +1,5 @@
 // { dg-xfail-if "ICE" { "*-*-*" } { "-fpph-map=pph.map" } }
-// { dg-bogus "internal compiler error: Segmentation fault" "" { xfail *-*-* } 
0 }
+// { dg-bogus "internal compiler error: in resume_scope" "" { xfail *-*-* } 0 }
 // { dg-prune-output "In file included from " }
 
 #include "x1namespace.h"
diff --git a/gcc/testsuite/g++.dg/pph/x1template.cc 
b/gcc/testsuite/g++.dg/pph/x1template.cc
index fbcb1bf..2cb1194 100644
--- a/gcc/testsuite/g++.dg/pph/x1template.cc
+++ b/gcc/testsuite/g++.dg/pph/x1template.cc
@@ -1,7 +1,3 @@
-/* { dg-xfail-if "ICE" { "*-*-*" } { "-fpph-map=pph.map" } } */
-// { dg-bogus "internal compiler error: Segmentation fault" "" { xfail *-*-* } 
0 }
-// { dg-prune-output "In file included from" }
-// pph asm xdiff
 #include "x1template.h"
 
 int x = 3;


--
This patch is available for review at http://codereview.appspot.com/4662067

Reply via email to