From 3dfaf1d7dbe64f27aa61388f18971b53a923db9f Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 1 Jun 2012 12:55:17 -0400 Subject: [PATCH] re PR c++/53137 (g++ segfault) PR c++/53137 * pt.c (instantiate_class_template_1): Set LAMBDA_EXPR_THIS_CAPTURE. (instantiate_decl): Don't push_to_top_level for local class methods. (instantiate_class_template_1): Or for local classes. From-SVN: r188117 --- gcc/cp/ChangeLog | 5 ++++ gcc/cp/pt.c | 28 +++++++++++++++---- gcc/testsuite/ChangeLog | 3 ++ .../g++.dg/cpp0x/lambda/lambda-template5.C | 17 +++++++++++ 4 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template5.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 62f18fad6b4..781f7501394 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2012-06-01 Jason Merrill + PR c++/53137 + * pt.c (instantiate_class_template_1): Set LAMBDA_EXPR_THIS_CAPTURE. + (instantiate_decl): Don't push_to_top_level for local class methods. + (instantiate_class_template_1): Or for local classes. + PR c++/53484 * pt.c (do_auto_deduction): Don't try to deduce from a type-dependent initializer. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index b58dd13672f..4d4e8ada80f 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -8698,6 +8698,7 @@ instantiate_class_template_1 (tree type) tree pbinfo; tree base_list; unsigned int saved_maximum_field_alignment; + tree fn_context; if (type == error_mark_node) return error_mark_node; @@ -8756,7 +8757,9 @@ instantiate_class_template_1 (tree type) it now. */ push_deferring_access_checks (dk_no_deferred); - push_to_top_level (); + fn_context = decl_function_context (TYPE_MAIN_DECL (type)); + if (!fn_context) + push_to_top_level (); /* Use #pragma pack from the template context. */ saved_maximum_field_alignment = maximum_field_alignment; maximum_field_alignment = TYPE_PRECISION (pattern); @@ -9154,8 +9157,14 @@ instantiate_class_template_1 (tree type) tree decl = lambda_function (type); if (decl) { + tree lam = CLASSTYPE_LAMBDA_EXPR (type); + LAMBDA_EXPR_THIS_CAPTURE (lam) + = lookup_field_1 (type, get_identifier ("__this"), false); + instantiate_decl (decl, false, false); maybe_add_lambda_conv_op (type); + + LAMBDA_EXPR_THIS_CAPTURE (lam) = NULL_TREE; } else gcc_assert (errorcount); @@ -9186,7 +9195,8 @@ instantiate_class_template_1 (tree type) perform_deferred_access_checks (); pop_nested_class (); maximum_field_alignment = saved_maximum_field_alignment; - pop_from_top_level (); + if (!fn_context) + pop_from_top_level (); pop_deferring_access_checks (); pop_tinst_level (); @@ -18435,9 +18445,10 @@ instantiate_decl (tree d, int defer_ok, tree spec; tree gen_tmpl; bool pattern_defined; - int need_push; location_t saved_loc = input_location; bool external_p; + tree fn_context; + bool nested; /* This function should only be used to instantiate templates for functions and static member variables. */ @@ -18672,9 +18683,12 @@ instantiate_decl (tree d, int defer_ok, goto out; } - need_push = !cfun || !global_bindings_p (); - if (need_push) + fn_context = decl_function_context (d); + nested = (current_function_decl != NULL_TREE); + if (!fn_context) push_to_top_level (); + else if (nested) + push_function_context (); /* Mark D as instantiated so that recursive calls to instantiate_decl do not try to instantiate it again. */ @@ -18784,8 +18798,10 @@ instantiate_decl (tree d, int defer_ok, /* We're not deferring instantiation any more. */ TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (d)) = 0; - if (need_push) + if (!fn_context) pop_from_top_level (); + else if (nested) + pop_function_context (); out: input_location = saved_loc; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0c8a656c133..27dbddca0d4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2012-06-01 Jason Merrill + PR c++/53137 + * g++.dg/cpp0x/lambda/lambda-template5.C: New. + PR c++/53484 * g++.dg/cpp0x/auto33.C: New. diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template5.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template5.C new file mode 100644 index 00000000000..b91b89ff36c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template5.C @@ -0,0 +1,17 @@ +// PR c++/53137 +// { dg-do compile { target c++11 } } + +struct A +{ + template void f(); + + template void g() + { + [this]{ f(); }(); + } + + void h() + { + g(); + } +};