diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-08-15 21:59:40 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-08-15 21:59:40 +0000 |
commit | 64d8d39e1f719bd083cb3bb3a228c07d696f98bf (patch) | |
tree | e67cb1575d9bbab9d61cafcb08483a12596b5273 | |
parent | 55f8fa93780d484f1dcab9aa35b78bb3a28ff0f7 (diff) | |
download | gcc-64d8d39e1f719bd083cb3bb3a228c07d696f98bf.tar.gz |
PR c++/61566
* pt.c (instantiate_class_template_1): Ignore lambda on
CLASSTYPE_DECL_LIST.
(push_template_decl_real): A lambda is not primary.
(lookup_template_class_1): Don't look for a lambda partial
instantiation.
* lambda.c (maybe_add_lambda_conv_op): Distinguish between being
currently in a function and the lambda living in a function.
* mangle.c (CLASSTYPE_TEMPLATE_ID_P): False for lambda.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@214046 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/cp/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/cp/lambda.c | 5 | ||||
-rw-r--r-- | gcc/cp/mangle.c | 1 | ||||
-rw-r--r-- | gcc/cp/pt.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template13.C | 6 |
5 files changed, 31 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e57131f716e..c926978bdcd 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,15 @@ +2014-08-15 Jason Merrill <jason@redhat.com> + + PR c++/61566 + * pt.c (instantiate_class_template_1): Ignore lambda on + CLASSTYPE_DECL_LIST. + (push_template_decl_real): A lambda is not primary. + (lookup_template_class_1): Don't look for a lambda partial + instantiation. + * lambda.c (maybe_add_lambda_conv_op): Distinguish between being + currently in a function and the lambda living in a function. + * mangle.c (CLASSTYPE_TEMPLATE_ID_P): False for lambda. + 2014-08-15 Richard Biener <rguenther@suse.de> Jason Merrill <jason@redhat.com> diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c index 169f438e562..ddaa9406727 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/mangle.c b/gcc/cp/mangle.c index 40508ab0cc3..ac165e021d9 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -87,6 +87,7 @@ along with GCC; see the file COPYING3. If not see (TYPE_LANG_SPECIFIC (NODE) != NULL \ && (TREE_CODE (NODE) == BOUND_TEMPLATE_TEMPLATE_PARM \ || (CLASSTYPE_TEMPLATE_INFO (NODE) != NULL \ + && !LAMBDA_TYPE_P (NODE) \ && (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (NODE)))))) /* Things we only need one of. This module is not reentrant. */ diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 6a7bcb819c2..611bfd6b7a1 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 <typename T> friend void A<T>::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 (); @@ -7875,6 +7878,8 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context, && TMPL_ARGS_HAVE_MULTIPLE_LEVELS (arglist) /* the enclosing class must be an instantiation... */ && CLASS_TYPE_P (context) + /* We don't do partial instantiation of closures. */ + && !LAMBDA_TYPE_P (TREE_TYPE (gen_tmpl)) && !same_type_p (context, DECL_CONTEXT (gen_tmpl))) { tree partial_inst_args; @@ -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 adbb4dbcaac..2b1a605acd0 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 <class U> struct C { template <typename T> @@ -15,6 +16,9 @@ struct C void bar () { - C c; + C<int> c; c.foo (1); } + +// { dg-final { scan-assembler "_ZN8functionC1IZN1CIiE3fooIiEEvT_S_Ed_UlvE_EET_" } } +// { dg-final { scan-assembler-not "_ZZN1CIiE3fooIiEEvT_8functionEd_NKUlvE_clEv" } } |