diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 57c80275bd6..bdc1f41268c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2006-04-30 Mark Mitchell + + PR c++/27094 + * pt.c (tsubst_default_argument): Increment function_depth around + call to tsubst_expr. + * parser.c (cp_parser_parameter_declaration): Likewise. + * decl2.c (mark_used): Tidy. + 2006-04-30 Volker Reichelt PR c++/27278 diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index fe5db71c653..df85e4cba7b 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -3319,29 +3319,28 @@ mark_used (tree decl) { synthesize_method (decl); /* If we've already synthesized the method we don't need to - instantiate it, so we can return right away. */ - return; + do the instantiation test below. */ } - - /* If this is a function or variable that is an instance of some - template, we now know that we will need to actually do the - instantiation. We check that DECL is not an explicit - instantiation because that is not checked in instantiate_decl. */ - if ((DECL_NON_THUNK_FUNCTION_P (decl) || TREE_CODE (decl) == VAR_DECL) - && DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl) - && (!DECL_EXPLICIT_INSTANTIATION (decl) - || (TREE_CODE (decl) == FUNCTION_DECL - && DECL_INLINE (DECL_TEMPLATE_RESULT - (template_for_substitution (decl)))) - /* We need to instantiate static data members so that there - initializers are available in integral constant - expressions. */ - || (TREE_CODE (decl) == VAR_DECL - && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl)))) - /* We put off instantiating functions in order to improve compile + else if ((DECL_NON_THUNK_FUNCTION_P (decl) || TREE_CODE (decl) == VAR_DECL) + && DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl) + && (!DECL_EXPLICIT_INSTANTIATION (decl) + || (TREE_CODE (decl) == FUNCTION_DECL + && DECL_INLINE (DECL_TEMPLATE_RESULT + (template_for_substitution (decl)))) + /* We need to instantiate static data members so that there + initializers are available in integral constant + expressions. */ + || (TREE_CODE (decl) == VAR_DECL + && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl)))) + /* If this is a function or variable that is an instance of some + template, we now know that we will need to actually do the + instantiation. We check that DECL is not an explicit + instantiation because that is not checked in instantiate_decl. + + We put off instantiating functions in order to improve compile times. Maintaining a stack of active functions is expensive, and the inliner knows to instantiate any functions it might - need. */ + need. Therefore, we always try to defer instantiation. */ instantiate_decl (decl, /*defer_ok=*/true, /*expl_inst_class_mem_p=*/false); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index f673c16bacf..ff8086fd559 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -12431,10 +12431,17 @@ cp_parser_parameter_declaration (cp_parser *parser, 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. */ default_argument = cp_parser_assignment_expression (parser, /*cast_p=*/false); /* Restore saved state. */ + --function_depth; parser->greater_than_is_operator_p = saved_greater_than_is_operator_p; parser->local_variables_forbidden_p diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index fbe01dbfb41..43efc63a3af 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -6150,8 +6150,15 @@ tsubst_default_argument (tree fn, tree type, tree arg) } push_deferring_access_checks(dk_no_deferred); + /* 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; arg = tsubst_expr (arg, DECL_TI_ARGS (fn), tf_warning_or_error, NULL_TREE); + --function_depth; pop_deferring_access_checks(); /* Restore the "this" pointer. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b82e646e90d..b9ca4cff981 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2006-04-30 Mark Mitchell + + PR c++/27094 + * g++.dg/template/defarg8.C: New test. + 2006-04-30 Volker Reichelt PR c++/27278 diff --git a/gcc/testsuite/g++.dg/template/defarg8.C b/gcc/testsuite/g++.dg/template/defarg8.C new file mode 100644 index 00000000000..61d819c7cdc --- /dev/null +++ b/gcc/testsuite/g++.dg/template/defarg8.C @@ -0,0 +1,19 @@ +// PR c++/27094 +// { dg-options "--param ggc-min-expand=0 --param ggc-min-heapsize=0" } + +struct A +{ + ~A(); +}; + +struct B : A +{ + B(); +}; + +template struct C +{ + C(const B& = B()); +}; + +C<0> c;