Commit ebfefb41 by Jason Merrill Committed by Jason Merrill

re PR c++/49672 ([C++0x] Internal error when passing variadic template args to a lambda function)

	PR c++/49672
	* pt.c (extract_fnparm_pack): Split out from...
	(make_fnparm_pack): ...here.
	(instantiate_decl): Handle non-pack parms after a pack.
	* semantics.c (maybe_add_lambda_conv_op): Don't in a template.

From-SVN: r176183
parent d983a802
2011-07-11 Jason Merrill <jason@redhat.com> 2011-07-11 Jason Merrill <jason@redhat.com>
PR c++/49672
* pt.c (extract_fnparm_pack): Split out from...
(make_fnparm_pack): ...here.
(instantiate_decl): Handle non-pack parms after a pack.
* semantics.c (maybe_add_lambda_conv_op): Don't in a template.
* decl2.c (decl_constant_var_p): Use decl_maybe_constant_var_p. * decl2.c (decl_constant_var_p): Use decl_maybe_constant_var_p.
PR c++/44609 PR c++/44609
......
...@@ -8711,11 +8711,12 @@ tsubst_template_arg (tree t, tree args, tsubst_flags_t complain, tree in_decl) ...@@ -8711,11 +8711,12 @@ tsubst_template_arg (tree t, tree args, tsubst_flags_t complain, tree in_decl)
return r; return r;
} }
/* Give a chain SPEC_PARM of PARM_DECLs, pack them into a /* Given a function parameter pack TMPL_PARM and some function parameters
NONTYPE_ARGUMENT_PACK. */ instantiated from it at *SPEC_P, return a NONTYPE_ARGUMENT_PACK of them
and set *SPEC_P to point at the next point in the list. */
static tree static tree
make_fnparm_pack (tree spec_parm) extract_fnparm_pack (tree tmpl_parm, tree *spec_p)
{ {
/* Collect all of the extra "packed" parameters into an /* Collect all of the extra "packed" parameters into an
argument pack. */ argument pack. */
...@@ -8723,11 +8724,18 @@ make_fnparm_pack (tree spec_parm) ...@@ -8723,11 +8724,18 @@ make_fnparm_pack (tree spec_parm)
tree parmtypevec; tree parmtypevec;
tree argpack = make_node (NONTYPE_ARGUMENT_PACK); tree argpack = make_node (NONTYPE_ARGUMENT_PACK);
tree argtypepack = cxx_make_type (TYPE_ARGUMENT_PACK); tree argtypepack = cxx_make_type (TYPE_ARGUMENT_PACK);
int i, len = list_length (spec_parm); tree spec_parm = *spec_p;
int i, len;
for (len = 0; spec_parm; ++len, spec_parm = TREE_CHAIN (spec_parm))
if (tmpl_parm
&& !function_parameter_expanded_from_pack_p (spec_parm, tmpl_parm))
break;
/* Fill in PARMVEC and PARMTYPEVEC with all of the parameters. */ /* Fill in PARMVEC and PARMTYPEVEC with all of the parameters. */
parmvec = make_tree_vec (len); parmvec = make_tree_vec (len);
parmtypevec = make_tree_vec (len); parmtypevec = make_tree_vec (len);
spec_parm = *spec_p;
for (i = 0; i < len; i++, spec_parm = DECL_CHAIN (spec_parm)) for (i = 0; i < len; i++, spec_parm = DECL_CHAIN (spec_parm))
{ {
TREE_VEC_ELT (parmvec, i) = spec_parm; TREE_VEC_ELT (parmvec, i) = spec_parm;
...@@ -8738,9 +8746,19 @@ make_fnparm_pack (tree spec_parm) ...@@ -8738,9 +8746,19 @@ make_fnparm_pack (tree spec_parm)
SET_ARGUMENT_PACK_ARGS (argpack, parmvec); SET_ARGUMENT_PACK_ARGS (argpack, parmvec);
SET_ARGUMENT_PACK_ARGS (argtypepack, parmtypevec); SET_ARGUMENT_PACK_ARGS (argtypepack, parmtypevec);
TREE_TYPE (argpack) = argtypepack; TREE_TYPE (argpack) = argtypepack;
*spec_p = spec_parm;
return argpack; return argpack;
} }
/* Give a chain SPEC_PARM of PARM_DECLs, pack them into a
NONTYPE_ARGUMENT_PACK. */
static tree
make_fnparm_pack (tree spec_parm)
{
return extract_fnparm_pack (NULL_TREE, &spec_parm);
}
/* Substitute ARGS into T, which is an pack expansion /* Substitute ARGS into T, which is an pack expansion
(i.e. TYPE_PACK_EXPANSION or EXPR_PACK_EXPANSION). Returns a (i.e. TYPE_PACK_EXPANSION or EXPR_PACK_EXPANSION). Returns a
...@@ -17830,21 +17848,21 @@ instantiate_decl (tree d, int defer_ok, ...@@ -17830,21 +17848,21 @@ instantiate_decl (tree d, int defer_ok,
spec_parm = skip_artificial_parms_for (d, spec_parm); spec_parm = skip_artificial_parms_for (d, spec_parm);
tmpl_parm = skip_artificial_parms_for (subst_decl, tmpl_parm); tmpl_parm = skip_artificial_parms_for (subst_decl, tmpl_parm);
} }
while (tmpl_parm && !FUNCTION_PARAMETER_PACK_P (tmpl_parm)) for (; tmpl_parm; tmpl_parm = DECL_CHAIN (tmpl_parm))
{ {
register_local_specialization (spec_parm, tmpl_parm); if (!FUNCTION_PARAMETER_PACK_P (tmpl_parm))
tmpl_parm = DECL_CHAIN (tmpl_parm); {
spec_parm = DECL_CHAIN (spec_parm); register_local_specialization (spec_parm, tmpl_parm);
spec_parm = DECL_CHAIN (spec_parm);
}
else
{
/* Register the (value) argument pack as a specialization of
TMPL_PARM, then move on. */
tree argpack = extract_fnparm_pack (tmpl_parm, &spec_parm);
register_local_specialization (argpack, tmpl_parm);
}
} }
if (tmpl_parm && FUNCTION_PARAMETER_PACK_P (tmpl_parm))
{
/* Register the (value) argument pack as a specialization of
TMPL_PARM, then move on. */
tree argpack = make_fnparm_pack (spec_parm);
register_local_specialization (argpack, tmpl_parm);
tmpl_parm = DECL_CHAIN (tmpl_parm);
spec_parm = NULL_TREE;
}
gcc_assert (!spec_parm); gcc_assert (!spec_parm);
/* Substitute into the body of the function. */ /* Substitute into the body of the function. */
......
...@@ -8808,6 +8808,9 @@ maybe_add_lambda_conv_op (tree type) ...@@ -8808,6 +8808,9 @@ maybe_add_lambda_conv_op (tree type)
if (LAMBDA_EXPR_CAPTURE_LIST (CLASSTYPE_LAMBDA_EXPR (type)) != NULL_TREE) if (LAMBDA_EXPR_CAPTURE_LIST (CLASSTYPE_LAMBDA_EXPR (type)) != NULL_TREE)
return; return;
if (processing_template_decl)
return;
stattype = build_function_type (TREE_TYPE (TREE_TYPE (callop)), stattype = build_function_type (TREE_TYPE (TREE_TYPE (callop)),
FUNCTION_ARG_CHAIN (callop)); FUNCTION_ARG_CHAIN (callop));
......
// PR c++/49672
// { dg-options -std=c++0x }
template<typename ... Args>
static void foo()
{
[](Args..., int x) {
x;
};
}
int main()
{
foo();
}
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