This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Bootstrap failure with enable-checking in _Unwind_GetGR (Zack's function.c changes broken?)
- To: Andreas Jaeger <aj at suse dot de>
- Subject: Re: Bootstrap failure with enable-checking in _Unwind_GetGR (Zack's function.c changes broken?)
- From: Zack Weinberg <zack at codesourcery dot com>
- Date: Sat, 1 Sep 2001 10:40:53 -0700
- Cc: gcc-bugs at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- References: <u8wv3jmcik.fsf@gromit.moeb>
On Sat, Sep 01, 2001 at 12:27:47PM +0200, Andreas Jaeger wrote:
>
> make bootstrap fails:
...
> /cvs/gcc/gcc/unwind-dw2.c: In function `_Unwind_GetGR':
> /cvs/gcc/gcc/unwind-dw2.c:1182: Internal error: Segmentation fault
> Please submit a full bug report,
> with preprocessed source if appropriate.
That was an interesting one.
output_inline_function calls rest_of_compilation. As its last action,
rest_of_compilation calls free_after_compilation and then
ggc_collect. free_after_compilation destroys the current function
structure, causing cfun->eh to be garbage. It clears cfun before
calling ggc_collect, but it doesn't clear DECL_SAVED_INSNS, and the
garbage collector tries to look through DECL_SAVED_INSNS now.
output_inline_function _does_ clear DECL_SAVED_INSNS, which is why I
didn't catch this; without always-collect, the only way this bug can
trip is if the ggc_collect call right at the end of rest_of_compilation
happens to trigger a collection.
Here's a patch. Would you mind testing? If I try to do an
always-collect build it'll take three days. It has run to the end of
stage1, and I'm doing the C testsuite, which should only take the rest
of today.
The function.c change may not actually be necessary; I think we are
protected by pushed contexts in any case where f->outer is non-null.
But this is the Right Thing.
zw
* function.c (ggc_mark_struct_function): Follow f->outer.
* toplev.c (rest_of_compilation): Clear DECL_INLINE and
DECL_SAVED_INSNS here...
* integrate.c (output_inline_function): ... not here.
===================================================================
Index: function.c
--- function.c 2001/08/31 22:22:01 1.303
+++ function.c 2001/09/01 17:33:04
@@ -7703,6 +7703,8 @@ ggc_mark_struct_function (f)
ggc_mark_rtvec ((rtvec) f->original_arg_vector);
if (f->original_decl_initial)
ggc_mark_tree (f->original_decl_initial);
+ if (f->outer)
+ ggc_mark_struct_function (f->outer);
}
/* Called once, at initialization, to initialize function.c. */
===================================================================
Index: integrate.c
--- integrate.c 2001/08/31 22:22:02 1.159
+++ integrate.c 2001/09/01 17:33:05
@@ -2899,13 +2899,10 @@ output_inline_function (fndecl)
before it gets mangled by optimization. */
(*debug_hooks->outlining_inline_function) (fndecl);
- /* Compile this function all the way down to assembly code. */
+ /* Compile this function all the way down to assembly code. As a
+ side effect this destroys the saved RTL representation, but
+ that's okay, because we don't need to inline this anymore. */
rest_of_compilation (fndecl);
-
- /* We can't inline this anymore; rest_of_compilation destroyed the
- data structures describing the function. */
- DECL_INLINE (fndecl) = 0;
- DECL_SAVED_INSNS (fndecl) = 0;
cfun = old_cfun;
current_function_decl = old_cfun ? old_cfun->decl : 0;
===================================================================
Index: toplev.c
--- toplev.c 2001/08/22 14:35:48 1.509
+++ toplev.c 2001/09/01 17:33:06
@@ -3773,7 +3773,14 @@ rest_of_compilation (decl)
/* We're done with this function. Free up memory if we can. */
free_after_parsing (cfun);
if (! DECL_DEFER_OUTPUT (decl))
- free_after_compilation (cfun);
+ {
+ free_after_compilation (cfun);
+
+ /* Clear integrate.c's pointer to the cfun structure we just
+ destroyed. */
+ DECL_INLINE (decl) = 0;
+ DECL_SAVED_INSNS (decl) = 0;
+ }
cfun = 0;
ggc_collect ();