int variadic_args_p = 0;
int post_variadic_parms = 0;
+ /* Adjustment to nparms for fixed parameter packs. */
+ int fixed_pack_adjust = 0;
+ int fixed_packs = 0;
+ int missing = 0;
+
/* Likewise for parameters with default arguments. */
int default_p = 0;
|| (TREE_VEC_ELT (parms, nargs) != error_mark_node
&& !TREE_PURPOSE (TREE_VEC_ELT (parms, nargs))))))
{
+ bad_nargs:
if (complain & tf_error)
{
if (variadic_p || default_p)
lost++;
/* We are done with all of the arguments. */
arg_idx = nargs;
+ break;
}
else
{
pack_adjust = TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg)) - 1;
arg_idx += pack_adjust;
+ if (fixed_parameter_pack_p (TREE_VALUE (parm)))
+ {
+ ++fixed_packs;
+ fixed_pack_adjust += pack_adjust;
+ }
}
continue;
error ("template argument %d is invalid", arg_idx + 1);
}
else if (!arg)
- /* This only occurs if there was an error in the template
- parameter list itself (which we would already have
- reported) that we are trying to recover from, e.g., a class
- template with a parameter list such as
- template<typename..., typename>. */
- ++lost;
+ {
+ /* This can occur if there was an error in the template
+ parameter list itself (which we would already have
+ reported) that we are trying to recover from, e.g., a class
+ template with a parameter list such as
+ template<typename..., typename> (cpp0x/variadic150.C). */
+ ++lost;
+
+ /* This can also happen with a fixed parameter pack (71834). */
+ if (arg_idx >= nargs)
+ ++missing;
+ }
else
arg = convert_template_argument (TREE_VALUE (parm),
arg, new_args, complain,
cp_unevaluated_operand = saved_unevaluated_operand;
c_inhibit_evaluation_warnings = saved_inhibit_evaluation_warnings;
- if (variadic_p && arg_idx < nargs)
+ if (missing || arg_idx < nargs - variadic_args_p)
{
- if (complain & tf_error)
- {
- error ("wrong number of template arguments "
- "(%d, should be %d)", nargs, arg_idx);
- if (in_decl)
- error ("provided for %q+D", in_decl);
- }
- return error_mark_node;
+ /* If we had fixed parameter packs, we didn't know how many arguments we
+ actually needed earlier; now we do. */
+ nparms += fixed_pack_adjust;
+ variadic_p -= fixed_packs;
+ goto bad_nargs;
}
if (lost)
- return error_mark_node;
+ {
+ gcc_assert (!(complain & tf_error) || seen_error ());
+ return error_mark_node;
+ }
if (CHECKING_P && !NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args))
SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args,