PR c++/64382
* g++.dg/cpp1y/pr64382.C: New test.
---
gcc/cp/cp-tree.h | 1 +
gcc/cp/parser.c | 21 +++++++++++++++++++++
gcc/cp/semantics.c | 8 +++++---
gcc/testsuite/g++.dg/cpp1y/pr64382.C | 23 +++++++++++++++++++++++
4 files changed, 50 insertions(+), 3 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/cpp1y/pr64382.C
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 2a904a5..484f352 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5645,6 +5645,7 @@ extern bool maybe_clone_body (tree);
/* In parser.c */
extern tree cp_convert_range_for (tree, tree, tree, bool);
extern bool parsing_nsdmi (void);
+extern bool parsing_default_capturing_generic_lambda_in_template (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 ac91976..74b55df 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -18339,6 +18339,27 @@ parsing_nsdmi (void)
return false;
}
+/* Return true iff our current scope is a default capturing generic lambda
+ defined within a template. */
+
+bool
+parsing_default_capturing_generic_lambda_in_template (void)
+{
+ if (processing_template_decl && current_class_type)
+ if (tree lam = CLASSTYPE_LAMBDA_EXPR (current_class_type))
+ if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lam) != CPLD_NONE)
+ if (tree callop = lambda_function (lam))
+ if (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 true;
+ return false;
+}
+
/* Parse a late-specified return type, if any. This is not a separate
non-terminal, but part of a function declarator, which looks like
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 74af7e8..f1ab183 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -3450,9 +3450,11 @@ finish_id_expression (tree id_expression,
}
}
- /* If the name was dependent on a template parameter, we will
- resolve the name at instantiation time. */
- if (dependent_p)
+ /* 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
+ name at instantiation time. */
+ if (dependent_p
+ && !parsing_default_capturing_generic_lambda_in_template ())
{
/* Create a SCOPE_REF for qualified names, if the scope is
dependent. */
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr64382.C
b/gcc/testsuite/g++.dg/cpp1y/pr64382.C
new file mode 100644
index 0000000..ff552ac
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/pr64382.C
@@ -0,0 +1,23 @@
+// PR c++/64382
+// { dg-do compile { target c++1y } }
+
+template<typename T>
+struct my_queue
+{
+ void push(T)
+ {
+ }
+ void ice()
+ {
+ auto L = [=](auto &&v) {
+ push(v);
+ };
+ trav(L);
+ }
+ template<typename F>
+ void trav(F &&f)
+ {
+ f(T());
+ }
+};
+template struct my_queue<int>;
--
2.3.5