Hi, A few weeks ago I submitted a fix for a garbage collection issue I ran into involving -Wunused-local-typedefs [1]. The analysis for that patch still stands, but unfortunately the patch is wrong.
The problem is that the allocation reuse can't be removed otherwise the information about local typedefs for a parent function is lost after a nested function is parsed. I obviously missed that distinction the first time. This patch restores the previous behavior and just clears the 'x_cur_stmt_list' field to avoid the GC issue. The patch was tested by building mips-linux-gnu (to verify that the GC crash that I originally encountered is still fixed) and by bootstrapping and running the full test suite for i686-pc-linux-gnu. OK? P.S. If it is OK, then can someone commit for me (I don't have write access)? [1] http://gcc.gnu.org/ml/gcc-patches/2012-05/msg01936.html gcc/ 2012-06-20 Meador Inge <mead...@codesourcery.com> PR c/53702 * c-decl.c (c_push_function_context): Restore the behavior to reuse the language function allocated for -Wunused-local-typedefs. (c_pop_function_context): If necessary, clear the language function created in c_push_function_context. Always clear out the x_cur_stmt_list field of the restored language function. gcc/testsuite/ 2012-06-20 Meador Inge <mead...@codesourcery.com> PR c/53702 * gcc.dg/Wunused-local-typedefs.c: New testcase. Index: gcc/testsuite/gcc.dg/Wunused-local-typedefs.c =================================================================== --- gcc/testsuite/gcc.dg/Wunused-local-typedefs.c (revision 0) +++ gcc/testsuite/gcc.dg/Wunused-local-typedefs.c (revision 0) @@ -0,0 +1,36 @@ +/* Origin PR c/53702 + { dg-options "-Wunused-local-typedefs" } + { dg-do compile } +*/ + +/* Only test nested functions for C. More tests that work for C and C++ + can be found in c-c++-common. +*/ + +void +test0 () +{ + typedef int foo; /* { dg-warning "locally defined but not used" } */ + void f () + { + } +} + +void +test1 () +{ + void f () + { + typedef int foo; /* { dg-warning "locally defined but not used" } */ + } +} + + +void +test2 () +{ + void f () + { + } + typedef int foo; /* { dg-warning "locally defined but not used" } */ +} Index: gcc/c-decl.c =================================================================== --- gcc/c-decl.c (revision 188841) +++ gcc/c-decl.c (working copy) @@ -8579,9 +8579,11 @@ check_for_loop_decls (location_t loc, bo void c_push_function_context (void) { - struct language_function *p; - p = ggc_alloc_language_function (); - cfun->language = p; + struct language_function *p = cfun->language; + /* cfun->language might have been already allocated by the use of + -Wunused-local-typedefs. In that case, just re-use it. */ + if (p == NULL) + cfun->language = p = ggc_alloc_cleared_language_function (); p->base.x_stmt_tree = c_stmt_tree; c_stmt_tree.x_cur_stmt_list @@ -8607,7 +8609,12 @@ c_pop_function_context (void) pop_function_context (); p = cfun->language; - cfun->language = NULL; + + /* When -Wunused-local-typedefs is in effect, cfun->languages is + used to store data throughout the life time of the current cfun, + So don't deallocate it. */ + if (!warn_unused_local_typedefs) + cfun->language = NULL; if (DECL_STRUCT_FUNCTION (current_function_decl) == 0 && DECL_SAVED_TREE (current_function_decl) == NULL_TREE) @@ -8620,6 +8627,7 @@ c_pop_function_context (void) } c_stmt_tree = p->base.x_stmt_tree; + p->base.x_stmt_tree.x_cur_stmt_list = NULL; c_break_label = p->x_break_label; c_cont_label = p->x_cont_label; c_switch_stack = p->x_switch_stack;