summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2017-09-18 18:37:16 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2017-09-18 18:37:16 +0000
commit0acce2b658c4312b74532a7510ed8629e8afabcb (patch)
treeafc1dfe4c4818fb861c5a48fd332d5ec4cecd21f
parent01fce95900955506a5a5d618edd1f6f4fe4603ec (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/parser.c9
-rw-r--r--gcc/cp/semantics.c8
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/lambda-generic-this1.C17
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/lambda-generic-this1a.C17
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() {}
+};