Commit e76b2472 by Jason Merrill Committed by Jason Merrill

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
parent f4942d79
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.
......
......@@ -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);
......
......@@ -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
......
// 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>();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment