diff options
author | Jason Merrill <jason@redhat.com> | 2017-09-06 21:02:46 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2017-09-06 21:02:46 -0400 |
commit | e76b247239756b547eaa51d9fa0629416a293269 (patch) | |
tree | 21aace7cb949e949bd716497d52d15eb2dd4193d | |
parent | f4942d79564674324584b98f5081cdcae3c6daa8 (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/pt.c | 21 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/lambda-defarg7.C | 13 |
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>(); +} |