diff options
author | Mark Mitchell <mark@codesourcery.com> | 2005-09-02 18:29:28 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2005-09-02 18:29:28 +0000 |
commit | da6110588f226bf6107910b7630451e736328a1b (patch) | |
tree | 132a35a0fae0655b2618067cb6bbe178be246bb7 /gcc | |
parent | 01be28d829b48b576564ce7d5c45570b0f42e2ee (diff) | |
download | gcc-da6110588f226bf6107910b7630451e736328a1b.zip gcc-da6110588f226bf6107910b7630451e736328a1b.tar.gz gcc-da6110588f226bf6107910b7630451e736328a1b.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/parser.c | 23 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/other/gc3.C | 8 |
4 files changed, 36 insertions, 6 deletions
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 <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 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 <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 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 <class Union> +void perform_test_trivial() { + struct check_union { void perform_test_trivial() {} }; +} + |