From 1f1066369684958fe1d698bd7c96785317cba087 Mon Sep 17 00:00:00 2001 From: mmitchel Date: Fri, 2 Sep 2005 18:29:28 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@103791 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/parser.c | 23 +++++++++++++++++------ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/other/gc3.C | 8 ++++++++ 4 files changed, 36 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/g++.dg/other/gc3.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d16d5f6..69e62c4 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 f6b5381..f066403 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 852641f..042a531 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 0000000..500d109 --- /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() {} }; +} + -- 2.7.4