This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Follow-up patch for removal of all_functions chain
- To: gcc-patches at gcc dot gnu dot org
- Subject: Follow-up patch for removal of all_functions chain
- From: Zack Weinberg <zack at codesourcery dot com>
- Date: Mon, 3 Sep 2001 11:18:15 -0700
- Cc: aj at suse dot de, mark at codesourcery dot com
This patch fixes a garbage collection bug introduced by my patch to
remove the all_functions chain. It is unlikely to trigger in real
life, Andreas found it in an ALWAYS_COLLECT build. At the end of
rest_of_compilation, the current-function structure is destroyed. If
the function is a deferred inline function, we must clear
DECL_SAVED_INSNS of its FUNCTION_DECL node before the next garbage
collection, or the mark phase will attempt to scan freed memory.
Also, we were marking only the top entry in the outer_function_chain,
which could have caused problems with a doubly nested function
(unlikely in C, but common in e.g. Pascal).
I was seeing a crash in cp/optimize.c during bootstrap, earlier this
weekend, but I can no longer reproduce it, and it didn't seem to be
related, anyway. Assuming the bootstrap I am running now completes
successfully (i686-linux), OK to apply?
zw
* function.c (ggc_mark_struct_function): Mark 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/03 17:54:05
@@ -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/03 17:54:06
@@ -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/03 17:54:07
@@ -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 ();