Re: [PATCH] PR c/53702: Fix -Wunused-local-typedefs with nested functions

2012-06-21 Thread Frank Ch. Eigler
Hi -

> This is OK.  You should have write-after-approval access.  Overseers, 
> please add user meadori to group gcc.

Done.

- FChE


Re: [PATCH] PR c/53702: Fix -Wunused-local-typedefs with nested functions

2012-06-21 Thread Joseph S. Myers
On Wed, 20 Jun 2012, Meador Inge wrote:

> P.S.  If it is OK, then can someone commit for me (I don't have write access)?

This is OK.  You should have write-after-approval access.  Overseers, 
please add user meadori to group gcc.

-- 
Joseph S. Myers
jos...@codesourcery.com


[PATCH] PR c/53702: Fix -Wunused-local-typedefs with nested functions

2012-06-20 Thread Meador Inge
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  

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  

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;