re PR c++/21687 (ICE in GC with local class inside a template function)
authorMark Mitchell <mark@codesourcery.com>
Fri, 2 Sep 2005 18:29:28 +0000 (18:29 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Fri, 2 Sep 2005 18:29:28 +0000 (18:29 +0000)
PR c++/21687
* parser.c (cp_parser_class_specifier): Push/pop GC contexts
around functions in local classes.

PR c++/21687
* g++.dg/other/gc3.C: New test.

From-SVN: r103791

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/other/gc3.C [new file with mode: 0644]

index d16d5f66d77a237ec5be90b07e0a414ff61b2143..69e62c4600a14f6505a69abf7b1b0bf4fe0d1eac 100644 (file)
@@ -1,3 +1,9 @@
+2005-09-02  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/21687
+       * parser.c (cp_parser_class_specifier): Push/pop GC contexts
+       around functions in local classes.
+
 2005-08-31  Andrew Pinski  <pinskia@physics.uc.edu>
 
        PR obj-c++/23640
index f6b5381f5a3cfb85d6864e06fcb5da31bc1ee285..f06640305bd41c2ff27b9bde7858560104c8e158 100644 (file)
@@ -12673,7 +12673,10 @@ cp_parser_class_specifier (cp_parser* parser)
       tree fn;
       tree class_type = NULL_TREE;
       tree pushed_scope = NULL_TREE;
-
+      /* True if we have called ggc_push_context, and therefore need
+        to make a matching call to ggc_pop_context.  */
+      bool need_ggc_pop_context;
       /* In a first pass, parse default arguments to the functions.
         Then, in a second pass, parse the bodies of the functions.
         This two-phased approach handles cases like:
@@ -12709,6 +12712,7 @@ cp_parser_class_specifier (cp_parser* parser)
        }
       if (pushed_scope)
        pop_scope (pushed_scope);
+      need_ggc_pop_context = false;
       /* Now parse the body of the functions.  */
       for (TREE_VALUE (parser->unparsed_functions_queues)
             = nreverse (TREE_VALUE (parser->unparsed_functions_queues));
@@ -12718,14 +12722,21 @@ cp_parser_class_specifier (cp_parser* parser)
        {
          /* Figure out which function we need to process.  */
          fn = TREE_VALUE (queue_entry);
-
-         /* A hack to prevent garbage collection.  */
-         function_depth++;
-
+         /* We call ggc_collect after processing a function body in
+            order to clean up garbage generated.  If we're processing
+            a local class, however, then we must not clean up stuff
+            from the function containing the class, so we have to
+            push a new garbage-collection context.  */
+         if (function_depth && !need_ggc_pop_context)
+           {
+             need_ggc_pop_context = true;
+             ggc_push_context ();
+           }
          /* Parse the function.  */
          cp_parser_late_parsing_for_member (parser, fn);
-         function_depth--;
        }
+      if (need_ggc_pop_context)
+       ggc_pop_context ();
     }
 
   /* Put back any saved access checks.  */
index 852641f79007781c1f6c1a23327742606043c372..042a5315321293cd504842b0a9983ff6e3c94482 100644 (file)
@@ -1,3 +1,8 @@
+2005-09-02  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/21687
+       * g++.dg/other/gc3.C: New test.
+
 2005-08-31  Andrew Pinski  <pinskia@physics.uc.edu>
 
        * gcc.dg/20030711-1.c: Include stddef.h and stdio.h.
diff --git a/gcc/testsuite/g++.dg/other/gc3.C b/gcc/testsuite/g++.dg/other/gc3.C
new file mode 100644 (file)
index 0000000..500d109
--- /dev/null
@@ -0,0 +1,8 @@
+// PR c++/21687
+// { dg-options "--param ggc-min-expand=0 --param ggc-min-heapsize=0" }
+
+template <class Union>
+void perform_test_trivial() {
+  struct check_union {  void perform_test_trivial() {} };
+}
+