diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2017-09-18 18:37:16 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2017-09-18 18:37:16 +0000 |
commit | 0acce2b658c4312b74532a7510ed8629e8afabcb (patch) | |
tree | afc1dfe4c4818fb861c5a48fd332d5ec4cecd21f | |
parent | 01fce95900955506a5a5d618edd1f6f4fe4603ec (diff) | |
download | gcc-0acce2b658c4312b74532a7510ed8629e8afabcb.tar.gz |
PR c++/81236 - ICE with template-id in generic lambda
* parser.c (parsing_default_capturing_generic_lambda): Don't check
for enclosing template.
* semantics.c (finish_qualified_id_expr): Call it.
* cp-tree.h: Adjust.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-7-branch@252946 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 2 | ||||
-rw-r--r-- | gcc/cp/parser.c | 9 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/lambda-generic-this1.C | 17 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/lambda-generic-this1a.C | 17 |
6 files changed, 48 insertions, 11 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 99c6ca7d78c..72cb0b4986e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 2017-09-18 Jason Merrill <jason@redhat.com> + PR c++/81236 - ICE with template-id in generic lambda + * parser.c (parsing_default_capturing_generic_lambda): Don't check + for enclosing template. + * semantics.c (finish_qualified_id_expr): Call it. + * cp-tree.h: Adjust. + PR c++/80767 - unnecessary instantiation of generic lambda PR c++/82030 - ICE inheriting from multiple lambdas * call.c (convert_like_real): Call build_user_type_conversion_1 if diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 9481160e576..4397101ef2e 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6125,7 +6125,7 @@ extern bool maybe_clone_body (tree); /* In parser.c */ extern tree cp_convert_range_for (tree, tree, tree, tree, unsigned int, bool); extern bool parsing_nsdmi (void); -extern bool parsing_default_capturing_generic_lambda_in_template (void); +extern bool parsing_default_capturing_generic_lambda (void); extern void inject_this_parameter (tree, cp_cv_quals); /* in pt.c */ diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 79aea4a290f..d2904e920b8 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -20486,7 +20486,7 @@ parsing_nsdmi (void) which we ultimately want to defer to instantiation time. */ bool -parsing_default_capturing_generic_lambda_in_template (void) +parsing_default_capturing_generic_lambda (void) { if (!processing_template_decl || !current_class_type) return false; @@ -20499,12 +20499,7 @@ parsing_default_capturing_generic_lambda_in_template (void) if (!callop) return false; - return (DECL_TEMPLATE_INFO (callop) - && (DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (callop)) == callop) - && ((current_nonlambda_class_type () - && CLASSTYPE_TEMPLATE_INFO (current_nonlambda_class_type ())) - || ((current_nonlambda_function () - && DECL_TEMPLATE_INFO (current_nonlambda_function ()))))); + return generic_lambda_fn_p (callop); } /* Parse a late-specified return type, if any. This is not a separate diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index ecfa4e25765..e0663764638 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2008,7 +2008,9 @@ finish_qualified_id_expr (tree qualifying_class, qualifying_class); pop_deferring_access_checks (); } - else if (BASELINK_P (expr) && !processing_template_decl) + else if (BASELINK_P (expr) + && (!processing_template_decl + || parsing_default_capturing_generic_lambda ())) { /* See if any of the functions are non-static members. */ /* If so, the expression may be relative to 'this'. */ @@ -3584,12 +3586,12 @@ finish_id_expression (tree id_expression, : CP_ID_KIND_UNQUALIFIED))); /* If the name was dependent on a template parameter and we're not in a - default capturing generic lambda within a template, we will resolve the + default capturing generic lambda, we will resolve the name at instantiation time. FIXME: For lambdas, we should defer building the closure type until instantiation time then we won't need the extra test here. */ if (dependent_p - && !parsing_default_capturing_generic_lambda_in_template ()) + && !parsing_default_capturing_generic_lambda ()) { if (DECL_P (decl) && any_dependent_type_attributes_p (DECL_ATTRIBUTES (decl))) diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-this1.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-this1.C new file mode 100644 index 00000000000..52d25af9c5a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-this1.C @@ -0,0 +1,17 @@ +// PR c++/81236 +// { dg-do compile { target c++14 } } + +struct A { constexpr operator int() { return 24; } }; + +struct MyType { + void crash() { + auto l = [&](auto i){ + make_crash<i>(); // Line (1) + }; + + l(A{}); + } + + template<int i> + void make_crash() {} +}; diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-this1a.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-this1a.C new file mode 100644 index 00000000000..d321a0773ee --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-this1a.C @@ -0,0 +1,17 @@ +// PR c++/81236 +// { dg-do compile { target c++14 } } + +struct A { constexpr operator int() { return 24; } }; + +struct MyType { + void crash() { + auto l = [&](auto i){ + MyType::make_crash<i>(); // Line (1) + }; + + l(A{}); + } + + template<int i> + void make_crash() {} +}; |