Commit 812c0795 by Jason Merrill Committed by Jason Merrill

PR c++/84338 - wrong variadic sizeof.

	* pt.c (argument_pack_select_arg): Like the macro, but look through
	a pack expansion.
	(tsubst, tsubst_copy, dependent_template_arg_p): Use it.
	(extract_fnparm_pack): Do make_pack_expansion.
	(extract_locals_r): Do strip a pack expansion.
	* cp-tree.h (ARGUMENT_PACK_SELECT_ARG): Remove.

From-SVN: r257626
parent 1bbae651
2018-02-13 Jason Merrill <jason@redhat.com>
PR c++/84338 - wrong variadic sizeof.
* pt.c (argument_pack_select_arg): Like the macro, but look through
a pack expansion.
(tsubst, tsubst_copy, dependent_template_arg_p): Use it.
(extract_fnparm_pack): Do make_pack_expansion.
(extract_locals_r): Do strip a pack expansion.
* cp-tree.h (ARGUMENT_PACK_SELECT_ARG): Remove.
2018-02-12 Jakub Jelinek <jakub@redhat.com>
PR c++/84341
......
......@@ -3558,12 +3558,6 @@ extern void decl_shadowed_for_var_insert (tree, tree);
#define ARGUMENT_PACK_SELECT_INDEX(NODE) \
(((struct tree_argument_pack_select *)ARGUMENT_PACK_SELECT_CHECK (NODE))->index)
/* In an ARGUMENT_PACK_SELECT, the actual underlying argument that the
ARGUMENT_PACK_SELECT represents. */
#define ARGUMENT_PACK_SELECT_ARG(NODE) \
TREE_VEC_ELT (ARGUMENT_PACK_ARGS (ARGUMENT_PACK_SELECT_FROM_PACK (NODE)), \
ARGUMENT_PACK_SELECT_INDEX (NODE))
#define FOLD_EXPR_CHECK(NODE) \
TREE_CHECK4 (NODE, UNARY_LEFT_FOLD_EXPR, UNARY_RIGHT_FOLD_EXPR, \
BINARY_LEFT_FOLD_EXPR, BINARY_RIGHT_FOLD_EXPR)
......
......@@ -3394,6 +3394,34 @@ get_template_argument_pack_elems (const_tree t)
return ARGUMENT_PACK_ARGS (t);
}
/* In an ARGUMENT_PACK_SELECT, the actual underlying argument that the
ARGUMENT_PACK_SELECT represents. */
static tree
argument_pack_select_arg (tree t)
{
tree args = ARGUMENT_PACK_ARGS (ARGUMENT_PACK_SELECT_FROM_PACK (t));
tree arg = TREE_VEC_ELT (args, ARGUMENT_PACK_SELECT_INDEX (t));
/* If the selected argument is an expansion E, that most likely means we were
called from gen_elem_of_pack_expansion_instantiation during the
substituting of an argument pack (of which the Ith element is a pack
expansion, where I is ARGUMENT_PACK_SELECT_INDEX) into a pack expansion.
In this case, the Ith element resulting from this substituting is going to
be a pack expansion, which pattern is the pattern of E. Let's return the
pattern of E, and gen_elem_of_pack_expansion_instantiation will build the
resulting pack expansion from it. */
if (PACK_EXPANSION_P (arg))
{
/* Make sure we aren't throwing away arg info. */
gcc_assert (!PACK_EXPANSION_EXTRA_ARGS (arg));
arg = PACK_EXPANSION_PATTERN (arg);
}
return arg;
}
/* True iff FN is a function representing a built-in variadic parameter
pack. */
......@@ -10933,7 +10961,12 @@ extract_fnparm_pack (tree tmpl_parm, tree *spec_p)
parmvec = make_tree_vec (len);
spec_parm = *spec_p;
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. */
SET_ARGUMENT_PACK_ARGS (argpack, parmvec);
......@@ -11388,7 +11421,8 @@ extract_locals_r (tree *tp, int */*walk_subtrees*/, void *data)
/* Pull out the actual PARM_DECL for the partial instantiation. */
tree args = ARGUMENT_PACK_ARGS (spec);
gcc_assert (TREE_VEC_LENGTH (args) == 1);
spec = TREE_VEC_ELT (args, 0);
tree arg = TREE_VEC_ELT (args, 0);
spec = PACK_EXPANSION_PATTERN (arg);
}
*extra = tree_cons (*tp, spec, *extra);
}
......@@ -13747,29 +13781,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
{
arg = TMPL_ARG (args, level, idx);
/* See through ARGUMENT_PACK_SELECT arguments. */
if (arg && TREE_CODE (arg) == ARGUMENT_PACK_SELECT)
{
/* See through ARGUMENT_PACK_SELECT arguments. */
arg = ARGUMENT_PACK_SELECT_ARG (arg);
/* If the selected argument is an expansion E, that most
likely means we were called from
gen_elem_of_pack_expansion_instantiation during the
substituting of pack an argument pack (which Ith
element is a pack expansion, where I is
ARGUMENT_PACK_SELECT_INDEX) into a pack expansion.
In this case, the Ith element resulting from this
substituting is going to be a pack expansion, which
pattern is the pattern of E. Let's return the
pattern of E, and
gen_elem_of_pack_expansion_instantiation will
build the resulting pack expansion from it. */
if (PACK_EXPANSION_P (arg))
{
/* Make sure we aren't throwing away arg info. */
gcc_assert (!PACK_EXPANSION_EXTRA_ARGS (arg));
arg = PACK_EXPANSION_PATTERN (arg);
}
}
arg = argument_pack_select_arg (arg);
}
if (arg == error_mark_node)
......@@ -14734,7 +14748,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
}
if (TREE_CODE (r) == ARGUMENT_PACK_SELECT)
r = ARGUMENT_PACK_SELECT_ARG (r);
r = argument_pack_select_arg (r);
if (!mark_used (r, complain) && !(complain & tf_error))
return error_mark_node;
return r;
......@@ -14866,7 +14880,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
register_local_specialization (r, t);
}
if (TREE_CODE (r) == ARGUMENT_PACK_SELECT)
r = ARGUMENT_PACK_SELECT_ARG (r);
r = argument_pack_select_arg (r);
}
else
r = t;
......@@ -24701,7 +24715,7 @@ dependent_template_arg_p (tree arg)
return true;
if (TREE_CODE (arg) == ARGUMENT_PACK_SELECT)
arg = ARGUMENT_PACK_SELECT_ARG (arg);
arg = argument_pack_select_arg (arg);
if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
return true;
......
// PR c++/84338
// { dg-do compile { target c++14 } }
template < typename ... T >
auto f(T ... i){
[](auto ... i){
// // wrongly true in current trunk
// static_assert(sizeof...(i) == 1, "");
static_assert(sizeof...(i) == 2, "");
}(i ...);
}
int main(){
f(0, 1);
}
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