commit 55ef57277be5885a78bacf4e979a8def08e4fbb6 Author: Jason Merrill Date: Fri Aug 15 01:53:54 2014 -0400 PR c++/61566 * pt.c (instantiate_class_template_1): Ignore lambda on CLASSTYPE_DECL_LIST. (push_template_decl_real): A lambda is not primary. * lambda.c (maybe_add_lambda_conv_op): Distinguish between being currently in a function and the lambda living in a function. diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c index 169f438..ddaa940 100644 --- a/gcc/cp/lambda.c +++ b/gcc/cp/lambda.c @@ -824,6 +824,7 @@ void maybe_add_lambda_conv_op (tree type) { bool nested = (current_function_decl != NULL_TREE); + bool nested_def = decl_function_context (TYPE_MAIN_DECL (type)); tree callop = lambda_function (type); if (LAMBDA_EXPR_CAPTURE_LIST (CLASSTYPE_LAMBDA_EXPR (type)) != NULL_TREE) @@ -976,7 +977,7 @@ maybe_add_lambda_conv_op (tree type) DECL_NOT_REALLY_EXTERN (fn) = 1; DECL_DECLARED_INLINE_P (fn) = 1; DECL_ARGUMENTS (fn) = build_this_parm (fntype, TYPE_QUAL_CONST); - if (nested) + if (nested_def) DECL_INTERFACE_KNOWN (fn) = 1; if (generic_lambda_p) @@ -1016,7 +1017,7 @@ maybe_add_lambda_conv_op (tree type) DECL_NAME (arg) = NULL_TREE; DECL_CONTEXT (arg) = fn; } - if (nested) + if (nested_def) DECL_INTERFACE_KNOWN (fn) = 1; if (generic_lambda_p) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 6a7bcb8..611bfd6 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -4722,6 +4722,9 @@ push_template_decl_real (tree decl, bool is_friend) template friend void A::f(); is not primary. */ is_primary = false; + else if (TREE_CODE (decl) == TYPE_DECL + && LAMBDA_TYPE_P (TREE_TYPE (decl))) + is_primary = false; else is_primary = template_parm_scope_p (); @@ -9237,6 +9242,11 @@ instantiate_class_template_1 (tree type) && DECL_OMP_DECLARE_REDUCTION_P (r)) cp_check_omp_declare_reduction (r); } + else if (DECL_CLASS_TEMPLATE_P (t) + && LAMBDA_TYPE_P (TREE_TYPE (t))) + /* A closure type for a lambda in a default argument for a + member template. Ignore it; it will be instantiated with + the default argument. */; else { /* Build new TYPE_FIELDS. */ diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template13.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template13.C index adbb4db..2b1a605 100644 --- a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template13.C +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template13.C @@ -7,6 +7,7 @@ struct function function (_Functor); }; +template struct C { template @@ -15,6 +16,9 @@ struct C void bar () { - C c; + C c; c.foo (1); } + +// { dg-final { scan-assembler "_ZN8functionC1IZN1CIiE3fooIiEEvT_S_Ed_UlvE_EET_" } } +// { dg-final { scan-assembler-not "_ZZN1CIiE3fooIiEEvT_8functionEd_NKUlvE_clEv" } }