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