From: Mark Mitchell Date: Fri, 2 Sep 2005 18:29:28 +0000 (+0000) Subject: re PR c++/21687 (ICE in GC with local class inside a template function) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=da6110588f226bf6107910b7630451e736328a1b;p=gcc.git re PR c++/21687 (ICE in GC with local class inside a template function) 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d16d5f66d77..69e62c4600a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2005-09-02 Mark Mitchell + + PR c++/21687 + * parser.c (cp_parser_class_specifier): Push/pop GC contexts + around functions in local classes. + 2005-08-31 Andrew Pinski PR obj-c++/23640 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index f6b5381f5a3..f06640305bd 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -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. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 852641f7900..042a5315321 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2005-09-02 Mark Mitchell + + PR c++/21687 + * g++.dg/other/gc3.C: New test. + 2005-08-31 Andrew Pinski * 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 index 00000000000..500d109e0d7 --- /dev/null +++ b/gcc/testsuite/g++.dg/other/gc3.C @@ -0,0 +1,8 @@ +// PR c++/21687 +// { dg-options "--param ggc-min-expand=0 --param ggc-min-heapsize=0" } + +template +void perform_test_trivial() { + struct check_union { void perform_test_trivial() {} }; +} +