aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2017-09-06 21:02:46 -0400
committerJason Merrill <jason@gcc.gnu.org>2017-09-06 21:02:46 -0400
commite76b247239756b547eaa51d9fa0629416a293269 (patch)
tree21aace7cb949e949bd716497d52d15eb2dd4193d
parentf4942d79564674324584b98f5081cdcae3c6daa8 (diff)
downloadgcc-e76b247239756b547eaa51d9fa0629416a293269.zip
gcc-e76b247239756b547eaa51d9fa0629416a293269.tar.gz
gcc-e76b247239756b547eaa51d9fa0629416a293269.tar.bz2
PR c++/82053 - ICE with default argument in lambda in template
* pt.c (tsubst_arg_types): Substitute default arguments for lambdas in templates. (retrieve_specialization): Use lambda_fn_in_template_p. * cp-tree.h: Declare it. From-SVN: r251826
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/pt.c21
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/lambda-defarg7.C13
4 files changed, 30 insertions, 11 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index e497094..6c4a31d 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,11 @@
2017-09-06 Jason Merrill <jason@redhat.com>
+ PR c++/82053 - ICE with default argument in lambda in template
+ * pt.c (tsubst_arg_types): Substitute default arguments for lambdas
+ in templates.
+ (retrieve_specialization): Use lambda_fn_in_template_p.
+ * cp-tree.h: Declare it.
+
PR c++/82070 - error with nested lambda capture
* pt.c (tsubst_expr) [DECL_EXPR]: Register capture proxies with
register_local_specialization.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 20fa039..a0e31d3 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6821,6 +6821,7 @@ extern tree current_nonlambda_function (void);
extern tree nonlambda_method_basetype (void);
extern tree current_nonlambda_scope (void);
extern bool generic_lambda_fn_p (tree);
+extern bool lambda_fn_in_template_p (tree);
extern void maybe_add_lambda_conv_op (tree);
extern bool is_lambda_ignored_entity (tree);
extern bool lambda_static_thunk_p (tree);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 4a65e31..ec7bbc8 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -1193,16 +1193,8 @@ retrieve_specialization (tree tmpl, tree args, hashval_t hash)
/* Lambda functions in templates aren't instantiated normally, but through
tsubst_lambda_expr. */
- if (LAMBDA_FUNCTION_P (tmpl))
- {
- bool generic = PRIMARY_TEMPLATE_P (tmpl);
- if (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)) > generic)
- return NULL_TREE;
-
- /* But generic lambda functions are instantiated normally, once their
- containing context is fully instantiated. */
- gcc_assert (generic);
- }
+ if (lambda_fn_in_template_p (tmpl))
+ return NULL_TREE;
if (optimize_specialization_lookup_p (tmpl))
{
@@ -12579,7 +12571,7 @@ tsubst_template_decl (tree t, tree args, tsubst_flags_t complain,
bool
lambda_fn_in_template_p (tree fn)
{
- if (!LAMBDA_FUNCTION_P (fn))
+ if (!fn || !LAMBDA_FUNCTION_P (fn))
return false;
tree closure = DECL_CONTEXT (fn);
return CLASSTYPE_TEMPLATE_INFO (closure) != NULL_TREE;
@@ -13248,6 +13240,13 @@ tsubst_arg_types (tree arg_types,
done in build_over_call. */
default_arg = TREE_PURPOSE (arg_types);
+ /* Except that we do substitute default arguments under tsubst_lambda_expr,
+ since the new op() won't have any associated template arguments for us
+ to refer to later. */
+ if (lambda_fn_in_template_p (in_decl))
+ default_arg = tsubst_copy_and_build (default_arg, args, complain, in_decl,
+ false/*fn*/, false/*constexpr*/);
+
if (default_arg && TREE_CODE (default_arg) == DEFAULT_ARG)
{
/* We've instantiated a template before its default arguments
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-defarg7.C b/gcc/testsuite/g++.dg/cpp1y/lambda-defarg7.C
new file mode 100644
index 0000000..f67dfee
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-defarg7.C
@@ -0,0 +1,13 @@
+// PR c++/82053
+// { dg-do compile { target c++14 } }
+
+template<class T>
+int fn() { return 42; }
+
+template<class T>
+auto lam = [](int = fn<T>()){};
+
+int main()
+{
+ lam<int>();
+}