diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 630814a3c222d7cad1b329332ed96b01e4e14a30..7112a67df67a092e84b678305af0740d5234fa64 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2009-08-19 Jason Merrill <jason@redhat.com> + + PR c++/41119 + PR c++/41120 + * decl2.c (mark_used): Increment function_depth during synthesis. + * parser.c (cp_parser_default_argument): Not here. + 2009-08-19 Jakub Jelinek <jakub@redhat.com> * method.c (use_thunk): Call free_after_compilation after diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index e4ed9632b2db7133ce574d89e16c6432df8dc4b7..225cd9db310dfcb98d33f7e29bc472ce0a75fd50 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -3948,7 +3948,16 @@ mark_used (tree decl) && !DECL_THUNK_P (decl) && ! DECL_INITIAL (decl)) { + /* Synthesizing an implicitly defined member function will result in + garbage collection. We must treat this situation as if we were + within the body of a function so as to avoid collecting live data + on the stack (such as overload resolution candidates). + + ??? Now that inlining is done unit-at-a-time, we ought to defer + synthesis like we do templates. */ + ++function_depth; synthesize_method (decl); + --function_depth; /* If we've already synthesized the method we don't need to do the instantiation test below. */ } diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index e64d0bf7cbdcce7a8dd7831d12036b30ea2166a4..a3e9f0ebebcdc987ece171995012e59e6fd2069d 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -14615,12 +14615,6 @@ cp_parser_default_argument (cp_parser *parser, bool template_parm_p) appear in a default argument. */ saved_local_variables_forbidden_p = parser->local_variables_forbidden_p; parser->local_variables_forbidden_p = true; - /* The default argument expression may cause implicitly - defined member functions to be synthesized, which will - result in garbage collection. We must treat this - situation as if we were within the body of function so as - to avoid collecting live data on the stack. */ - ++function_depth; /* Parse the assignment-expression. */ if (template_parm_p) push_deferring_access_checks (dk_no_deferred); @@ -14628,8 +14622,6 @@ cp_parser_default_argument (cp_parser *parser, bool template_parm_p) = cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL); if (template_parm_p) pop_deferring_access_checks (); - /* Restore saved state. */ - --function_depth; parser->greater_than_is_operator_p = saved_greater_than_is_operator_p; parser->local_variables_forbidden_p = saved_local_variables_forbidden_p; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e766efcc3e455f6483057d25aba95a5796938d7f..a29294938c46030ae082785f7baa5ca5616e716d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-08-19 Jason Merrill <jason@redhat.com> + + PR c++/41120 + * g++.dg/other/gc4.C: New. + 2009-08-18 Michael Matz <matz@suse.de> * gfortran.dg/vect/vect-gems.f90: New test. diff --git a/gcc/testsuite/g++.dg/other/gc4.C b/gcc/testsuite/g++.dg/other/gc4.C new file mode 100644 index 0000000000000000000000000000000000000000..50c16b366db79a25b9bbbf6323d9197a280ccdef --- /dev/null +++ b/gcc/testsuite/g++.dg/other/gc4.C @@ -0,0 +1,14 @@ +// PR c++/41120 +// { dg-options "--param ggc-min-heapsize=0 --param ggc-min-expand=0" } + +struct A +{ + A(); +}; + +struct B +{ + A a; +}; + +B b;