re PR c++/31138 (ICE with ellipsis)
2007-03-31 Douglas Gregor <doug.gregor@gmail.com> PR c++/31138 PR c++/31140 PR c++/31141 * parser.c (declarator_can_be_parameter_pack): New. (cp_parser_template_parameter): Only parse the `...' if the declarator can be a parameter pack. (cp_parser_parameter_declaration): Ditto. Also, handle when TYPE is NULL. * pt.c (find_parameter_packs_r): Look into the bounds on integer types (they could be used as array bounds). (check_for_bare_parameter_packs): Deal with TEMPLATE_PARM_INDEX. (tsubst_pack_expansion): Handle failure to expand parameter packs. 2007-03-31 Douglas Gregor <doug.gregor@gmail.com> * g++.dg/parser/pr31138.C: New. * g++.dg/parser/pr31140.C: New. * g++.dg/parser/pr31141.C: New. From-SVN: r123380
This commit is contained in:
parent
d54a92b5f6
commit
d393153e7f
4 changed files with 90 additions and 18 deletions
|
@ -1,3 +1,19 @@
|
|||
2007-03-31 Douglas Gregor <doug.gregor@gmail.com>
|
||||
|
||||
PR c++/31138
|
||||
PR c++/31140
|
||||
PR c++/31141
|
||||
* parser.c (declarator_can_be_parameter_pack): New.
|
||||
(cp_parser_template_parameter): Only parse the `...' if the
|
||||
declarator can be a parameter pack.
|
||||
(cp_parser_parameter_declaration): Ditto. Also, handle when TYPE
|
||||
is NULL.
|
||||
* pt.c (find_parameter_packs_r): Look into the bounds on integer
|
||||
types (they could be used as array bounds).
|
||||
(check_for_bare_parameter_packs): Deal with TEMPLATE_PARM_INDEX.
|
||||
(tsubst_pack_expansion): Handle failure to expand parameter
|
||||
packs.
|
||||
|
||||
2007-03-30 Paolo Carlini <pcarlini@suse.de>
|
||||
|
||||
PR c++/26099
|
||||
|
|
|
@ -1055,6 +1055,36 @@ make_array_declarator (cp_declarator *element, tree bounds)
|
|||
return declarator;
|
||||
}
|
||||
|
||||
/* Determine whether the declarator we've seen so far can be a
|
||||
parameter pack, when followed by an ellipsis. */
|
||||
static bool
|
||||
declarator_can_be_parameter_pack (cp_declarator *declarator)
|
||||
{
|
||||
/* Search for a declarator name, or any other declarator that goes
|
||||
after the point where the ellipsis could appear in a parameter
|
||||
pack. If we find any of these, then this declarator can not be
|
||||
made into a parameter pack. */
|
||||
bool found = false;
|
||||
while (declarator && !found)
|
||||
{
|
||||
switch ((int)declarator->kind)
|
||||
{
|
||||
case cdk_id:
|
||||
case cdk_error:
|
||||
case cdk_array:
|
||||
case cdk_ptrmem:
|
||||
found = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
declarator = declarator->declarator;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return !found;
|
||||
}
|
||||
|
||||
cp_parameter_declarator *no_parameters;
|
||||
|
||||
/* Create a parameter declarator with the indicated DECL_SPECIFIERS,
|
||||
|
@ -9049,9 +9079,9 @@ cp_parser_template_parameter (cp_parser* parser, bool *is_non_type,
|
|||
marked as a parameter pack, then we have a parameter pack (that
|
||||
has no declarator); */
|
||||
if (!*is_parameter_pack
|
||||
&& cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
|
||||
&& cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS)
|
||||
&& declarator_can_be_parameter_pack (parameter_declarator->declarator))
|
||||
{
|
||||
|
||||
/* Consume the `...'. */
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
maybe_warn_variadic_templates ();
|
||||
|
@ -13095,32 +13125,35 @@ cp_parser_parameter_declaration (cp_parser *parser,
|
|||
cp_parser_attributes_opt (parser));
|
||||
}
|
||||
|
||||
/* If the next token is an ellipsis, and the type of the declarator
|
||||
contains parameter packs but it is not a TYPE_PACK_EXPANSION, then
|
||||
we actually have a parameter pack expansion expression. Otherwise,
|
||||
leave the ellipsis for a C-style variadic function. */
|
||||
/* If the next token is an ellipsis, and we have not seen a
|
||||
declarator name, and the type of the declarator contains parameter
|
||||
packs but it is not a TYPE_PACK_EXPANSION, then we actually have
|
||||
a parameter pack expansion expression. Otherwise, leave the
|
||||
ellipsis for a C-style variadic function. */
|
||||
token = cp_lexer_peek_token (parser->lexer);
|
||||
if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
|
||||
{
|
||||
tree type = decl_specifiers.type;
|
||||
|
||||
if (DECL_P (type))
|
||||
if (type && DECL_P (type))
|
||||
type = TREE_TYPE (type);
|
||||
|
||||
if (TREE_CODE (type) != TYPE_PACK_EXPANSION
|
||||
if (type
|
||||
&& TREE_CODE (type) != TYPE_PACK_EXPANSION
|
||||
&& declarator_can_be_parameter_pack (declarator)
|
||||
&& (!declarator || !declarator->parameter_pack_p)
|
||||
&& uses_parameter_packs (type))
|
||||
{
|
||||
/* Consume the `...'. */
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
maybe_warn_variadic_templates ();
|
||||
|
||||
/* Build a pack expansion type */
|
||||
if (declarator)
|
||||
declarator->parameter_pack_p = true;
|
||||
else
|
||||
decl_specifiers.type = make_pack_expansion (type);
|
||||
}
|
||||
/* Consume the `...'. */
|
||||
cp_lexer_consume_token (parser->lexer);
|
||||
maybe_warn_variadic_templates ();
|
||||
|
||||
/* Build a pack expansion type */
|
||||
if (declarator)
|
||||
declarator->parameter_pack_p = true;
|
||||
else
|
||||
decl_specifiers.type = make_pack_expansion (type);
|
||||
}
|
||||
}
|
||||
|
||||
/* The restriction on defining new types applies only to the type
|
||||
|
|
17
gcc/cp/pt.c
17
gcc/cp/pt.c
|
@ -2441,6 +2441,12 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
|
|||
*walk_subtrees = 0;
|
||||
return NULL_TREE;
|
||||
|
||||
case INTEGER_TYPE:
|
||||
walk_tree (&TYPE_MAX_VALUE (t), &find_parameter_packs_r,
|
||||
ppd, ppd->visited);
|
||||
*walk_subtrees = 0;
|
||||
return NULL_TREE;
|
||||
|
||||
default:
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
@ -2621,6 +2627,8 @@ check_for_bare_parameter_packs (tree t)
|
|||
if (TREE_CODE (pack) == TEMPLATE_TYPE_PARM
|
||||
|| TREE_CODE (pack) == TEMPLATE_TEMPLATE_PARM)
|
||||
name = TYPE_NAME (pack);
|
||||
else if (TREE_CODE (pack) == TEMPLATE_PARM_INDEX)
|
||||
name = DECL_NAME (TEMPLATE_PARM_DECL (pack));
|
||||
else
|
||||
name = DECL_NAME (pack);
|
||||
inform (" %qD", name);
|
||||
|
@ -6860,6 +6868,15 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
|
|||
if (arg_pack && TREE_CODE (arg_pack) == ARGUMENT_PACK_SELECT)
|
||||
arg_pack = ARGUMENT_PACK_SELECT_FROM_PACK (arg_pack);
|
||||
|
||||
if (arg_pack && !ARGUMENT_PACK_P (arg_pack))
|
||||
/* This can only happen if we forget to expand an argument
|
||||
pack somewhere else. Just return an error, silently. */
|
||||
{
|
||||
result = make_tree_vec (1);
|
||||
TREE_VEC_ELT (result, 0) = error_mark_node;
|
||||
return result;
|
||||
}
|
||||
|
||||
if (arg_pack)
|
||||
{
|
||||
int my_len =
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2007-03-31 Douglas Gregor <doug.gregor@gmail.com>
|
||||
|
||||
* g++.dg/parser/pr31138.C: New.
|
||||
* g++.dg/parser/pr31140.C: New.
|
||||
* g++.dg/parser/pr31141.C: New.
|
||||
|
||||
2007-03-30 Paolo Carlini <pcarlini@suse.de>
|
||||
|
||||
PR c++/26099
|
||||
|
|
Loading…
Add table
Reference in a new issue