Commit 018e9cb5 by Jason Merrill Committed by Jason Merrill

PR c++/82249 - wrong mismatched pack length error.

	* pt.c (extract_fnparm_pack, tsubst_pack_expansion): Handle
	unsubstituted function parameter pack.

From-SVN: r257018
parent a84aff58
2018-01-23 Jason Merrill <jason@redhat.com>
PR c++/82249 - wrong mismatched pack length error.
* pt.c (extract_fnparm_pack, tsubst_pack_expansion): Handle
unsubstituted function parameter pack.
2018-01-23 Paolo Carlini <paolo.carlini@oracle.com> 2018-01-23 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/83921 PR c++/83921
......
...@@ -10961,7 +10961,12 @@ extract_fnparm_pack (tree tmpl_parm, tree *spec_p) ...@@ -10961,7 +10961,12 @@ extract_fnparm_pack (tree tmpl_parm, tree *spec_p)
parmvec = make_tree_vec (len); parmvec = make_tree_vec (len);
spec_parm = *spec_p; 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 elt = spec_parm;
if (DECL_PACK_P (elt))
elt = make_pack_expansion (elt);
TREE_VEC_ELT (parmvec, i) = elt;
}
/* Build the argument packs. */ /* Build the argument packs. */
SET_ARGUMENT_PACK_ARGS (argpack, parmvec); SET_ARGUMENT_PACK_ARGS (argpack, parmvec);
...@@ -11414,6 +11419,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, ...@@ -11414,6 +11419,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
tree pattern; tree pattern;
tree pack, packs = NULL_TREE; tree pack, packs = NULL_TREE;
bool unsubstituted_packs = false; bool unsubstituted_packs = false;
bool unsubstituted_fn_pack = false;
int i, len = -1; int i, len = -1;
tree result; tree result;
hash_map<tree, tree> *saved_local_specializations = NULL; hash_map<tree, tree> *saved_local_specializations = NULL;
...@@ -11484,6 +11490,13 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, ...@@ -11484,6 +11490,13 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
else else
arg_pack = make_fnparm_pack (arg_pack); arg_pack = make_fnparm_pack (arg_pack);
} }
else if (argument_pack_element_is_expansion_p (arg_pack, 0))
/* This argument pack isn't fully instantiated yet. We set this
flag rather than clear arg_pack because we do want to do the
optimization below, and we don't want to substitute directly
into the pattern (as that would expose a NONTYPE_ARGUMENT_PACK
where it isn't expected). */
unsubstituted_fn_pack = true;
} }
else if (TREE_CODE (parm_pack) == FIELD_DECL) else if (TREE_CODE (parm_pack) == FIELD_DECL)
arg_pack = tsubst_copy (parm_pack, args, complain, in_decl); arg_pack = tsubst_copy (parm_pack, args, complain, in_decl);
...@@ -11521,7 +11534,8 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, ...@@ -11521,7 +11534,8 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
if (len < 0) if (len < 0)
len = my_len; len = my_len;
else if (len != my_len) else if (len != my_len
&& !unsubstituted_fn_pack)
{ {
if (!(complain & tf_error)) if (!(complain & tf_error))
/* Fail quietly. */; /* Fail quietly. */;
...@@ -11574,7 +11588,8 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, ...@@ -11574,7 +11588,8 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
/* We cannot expand this expansion expression, because we don't have /* We cannot expand this expansion expression, because we don't have
all of the argument packs we need. */ all of the argument packs we need. */
if (use_pack_expansion_extra_args_p (packs, len, unsubstituted_packs)) if (use_pack_expansion_extra_args_p (packs, len, (unsubstituted_packs
|| unsubstituted_fn_pack)))
{ {
/* We got some full packs, but we can't substitute them in until we /* We got some full packs, but we can't substitute them in until we
have values for all the packs. So remember these until then. */ have values for all the packs. So remember these until then. */
......
// PR c++/82249
// { dg-do compile { target c++14 } }
template<class T, class U> T calc (T t, U u) { return t; }
template <class... Ts> void sink(Ts...);
template < typename ... Ds >
void f(Ds ...) {
[](auto ... n){
sink (calc(n, Ds{}) ...);
}(Ds{} ...);
}
int main(){
f(); // Wrong error
f(0, 0); // Wrong error
f(0); // ICE
}
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