re PR c++/34051 (ICE in dependent_type_p with variadic templates)

2008-01-15  Douglas Gregor  <doug.gregor@gmail.com>

	PR c++/34051
	PR c++/34055
	PR c++/34102
	PR c++/34103
	* typeck.c (check_return_expr): If there are bare parameter packs
	in the return value, set it to error_mark_node.
	* tree.c (cp_walk_subtrees): Walk USING_DECL nodes.
	* pt.c (find_parameter_packs_r): Look at the type of
	IDENTIFIER_NODEs (e.g., for user-defined conversions).
	(check_for_bare_parameter_packs): Flip the result: now returns
	TRUE when there were bare parameter packs, FALSE otherwise.
	(push_template_decl_real): Deal with flipped result of
	check_for_bare_parameter_packs.
	* semantics.c (finish_cond): If there are bare parameter packs in
	the conditional, set it to error_mark_node.
	(finish_expr_stmt): If there are bare parameter packs in the
	expression, set it to error_mark_node.
	(finish_for_expr): Ditto.
	(finish_switch_cond): If there are bare parameter packs in
	the conditional, set it to error_mark_node.
	(finish_mem_initializers): If there are bare parameter packs in
	the member initializer, set it to error_mark_node.
	(finish_member_declaration): Check the attributes of the
	declaration for bare parameter packs, and remove the attributes if
	any have bare parameter packs.
	* parser.c (cp_parser_using_declaration): Check the using
	declaration for bare parameter packs.
	(cp_parser_base_clause): If there are bare parameter packs in a
	base specifier, don't add it to the chain.

2008-01-15  Douglas Gregor  <doug.gregor@gmail.com>

	PR c++/34051
	PR c++/34055
	PR c++/34102
	PR c++/34103
	* g++.dg/cpp0x/vt-34051-2.C: New.
	* g++.dg/cpp0x/vt-34102.C: New.
	* g++.dg/cpp0x/vt-34051.C: New.
	* g++.dg/cpp0x/vt-34055.C: New.
	* g++.dg/cpp0x/vt-34103.C: New.

From-SVN: r131547
This commit is contained in:
Douglas Gregor 2008-01-15 18:08:00 +00:00 committed by Doug Gregor
parent a022041e4c
commit 4439d02f0f
12 changed files with 147 additions and 22 deletions

View File

@ -1,3 +1,35 @@
2008-01-15 Douglas Gregor <doug.gregor@gmail.com>
PR c++/34051
PR c++/34055
PR c++/34102
PR c++/34103
* typeck.c (check_return_expr): If there are bare parameter packs
in the return value, set it to error_mark_node.
* tree.c (cp_walk_subtrees): Walk USING_DECL nodes.
* pt.c (find_parameter_packs_r): Look at the type of
IDENTIFIER_NODEs (e.g., for user-defined conversions).
(check_for_bare_parameter_packs): Flip the result: now returns
TRUE when there were bare parameter packs, FALSE otherwise.
(push_template_decl_real): Deal with flipped result of
check_for_bare_parameter_packs.
* semantics.c (finish_cond): If there are bare parameter packs in
the conditional, set it to error_mark_node.
(finish_expr_stmt): If there are bare parameter packs in the
expression, set it to error_mark_node.
(finish_for_expr): Ditto.
(finish_switch_cond): If there are bare parameter packs in
the conditional, set it to error_mark_node.
(finish_mem_initializers): If there are bare parameter packs in
the member initializer, set it to error_mark_node.
(finish_member_declaration): Check the attributes of the
declaration for bare parameter packs, and remove the attributes if
any have bare parameter packs.
* parser.c (cp_parser_using_declaration): Check the using
declaration for bare parameter packs.
(cp_parser_base_clause): If there are bare parameter packs in a
base specifier, don't add it to the chain.
2008-01-15 Douglas Gregor <doug.gregor@gmail.com>
PR c++/34314

View File

@ -11748,14 +11748,20 @@ cp_parser_using_declaration (cp_parser* parser,
{
/* Create the USING_DECL. */
decl = do_class_using_decl (parser->scope, identifier);
/* Add it to the list of members in this class. */
finish_member_declaration (decl);
if (check_for_bare_parameter_packs (&decl))
return false;
else
/* Add it to the list of members in this class. */
finish_member_declaration (decl);
}
else
{
decl = cp_parser_lookup_name_simple (parser, identifier);
if (decl == error_mark_node)
cp_parser_name_lookup_error (parser, identifier, decl, NULL);
else if (check_for_bare_parameter_packs (&decl))
return false;
else if (!at_namespace_scope_p ())
do_local_using_decl (decl, qscope, identifier);
else
@ -15263,11 +15269,13 @@ cp_parser_base_clause (cp_parser* parser)
if (pack_expansion_p)
/* Make this a pack expansion type. */
TREE_VALUE (base) = make_pack_expansion (TREE_VALUE (base));
else
check_for_bare_parameter_packs (&TREE_VALUE (base));
TREE_CHAIN (base) = bases;
bases = base;
if (!check_for_bare_parameter_packs (&TREE_VALUE (base)))
{
TREE_CHAIN (base) = bases;
bases = base;
}
}
/* Peek at the next token. */
token = cp_lexer_peek_token (parser->lexer);

View File

@ -2577,6 +2577,11 @@ recheck:
*walk_subtrees = 0;
return NULL_TREE;
case IDENTIFIER_NODE:
cp_walk_tree (&TREE_TYPE (t), &find_parameter_packs_r, ppd, NULL);
*walk_subtrees = 0;
return NULL_TREE;
default:
return NULL_TREE;
}
@ -2731,8 +2736,8 @@ make_pack_expansion (tree arg)
g(h(args)), or f(g(h(args))), because we would produce erroneous
error messages.
Returns TRUE if there were no bare parameter packs, returns FALSE
(and emits an error) if there were bare parameter packs.*/
Returns TRUE and emits an error if there were bare parameter packs,
returns FALSE otherwise. */
bool
check_for_bare_parameter_packs (tree* t)
{
@ -2740,7 +2745,7 @@ check_for_bare_parameter_packs (tree* t)
struct find_parameter_pack_data ppd;
if (!processing_template_decl || !t || !*t || *t == error_mark_node)
return true;
return false;
if (TREE_CODE (*t) == TYPE_DECL)
t = &TREE_TYPE (*t);
@ -2783,10 +2788,10 @@ check_for_bare_parameter_packs (tree* t)
cp_walk_tree (t, &find_parameter_packs_r, &ppd, NULL);
pointer_set_destroy (ppd.visited);
return false;
return true;
}
return true;
return false;
}
/* Expand any parameter packs that occur in the template arguments in
@ -3885,7 +3890,7 @@ push_template_decl_real (tree decl, bool is_friend)
while (arg && argtype)
{
if (!FUNCTION_PARAMETER_PACK_P (arg)
&& !check_for_bare_parameter_packs (&TREE_TYPE (arg)))
&& check_for_bare_parameter_packs (&TREE_TYPE (arg)))
{
/* This is a PARM_DECL that contains unexpanded parameter
packs. We have already complained about this in the
@ -3901,14 +3906,14 @@ push_template_decl_real (tree decl, bool is_friend)
/* Check for bare parameter packs in the return type and the
exception specifiers. */
if (!check_for_bare_parameter_packs (&TREE_TYPE (type)))
if (check_for_bare_parameter_packs (&TREE_TYPE (type)))
/* Errors were already issued, set return type to int
as the frontend doesn't expect error_mark_node as
the return type. */
TREE_TYPE (type) = integer_type_node;
check_for_bare_parameter_packs (&TYPE_RAISES_EXCEPTIONS (type));
}
else if (!check_for_bare_parameter_packs (&TREE_TYPE (decl)))
else if (check_for_bare_parameter_packs (&TREE_TYPE (decl)))
return error_mark_node;
if (is_partial)

View File

@ -508,7 +508,8 @@ finish_cond (tree *cond_p, tree expr)
if (TREE_CODE (cond) == DECL_EXPR)
expr = cond;
check_for_bare_parameter_packs (&expr);
if (check_for_bare_parameter_packs (&expr))
*cond_p = error_mark_node;
}
*cond_p = expr;
}
@ -618,7 +619,8 @@ finish_expr_stmt (tree expr)
else if (!type_dependent_expression_p (expr))
convert_to_void (build_non_dependent_expr (expr), "statement");
check_for_bare_parameter_packs (&expr);
if (check_for_bare_parameter_packs (&expr))
expr = error_mark_node;
/* Simplification of inner statement expressions, compound exprs,
etc can result in us already having an EXPR_STMT. */
@ -875,7 +877,8 @@ finish_for_expr (tree expr, tree for_stmt)
else if (!type_dependent_expression_p (expr))
convert_to_void (build_non_dependent_expr (expr), "3rd expression in for");
expr = maybe_cleanup_point_expr_void (expr);
check_for_bare_parameter_packs (&expr);
if (check_for_bare_parameter_packs (&expr))
expr = error_mark_node;
FOR_EXPR (for_stmt) = expr;
}
@ -971,7 +974,8 @@ finish_switch_cond (tree cond, tree switch_stmt)
cond = index;
}
}
check_for_bare_parameter_packs (&cond);
if (check_for_bare_parameter_packs (&cond))
cond = error_mark_node;
finish_cond (&SWITCH_STMT_COND (switch_stmt), cond);
SWITCH_STMT_TYPE (switch_stmt) = orig_type;
add_stmt (switch_stmt);
@ -1388,8 +1392,9 @@ finish_mem_initializers (tree mem_inits)
any parameter packs in the TREE_VALUE have already been
bound as part of the TREE_PURPOSE. See
make_pack_expansion for more information. */
if (TREE_CODE (TREE_PURPOSE (mem)) != TYPE_PACK_EXPANSION)
check_for_bare_parameter_packs (&TREE_VALUE (mem));
if (TREE_CODE (TREE_PURPOSE (mem)) != TYPE_PACK_EXPANSION
&& check_for_bare_parameter_packs (&TREE_VALUE (mem)))
TREE_VALUE (mem) = error_mark_node;
}
add_stmt (build_min_nt (CTOR_INITIALIZER, mem_inits));
@ -2325,7 +2330,12 @@ finish_member_declaration (tree decl)
/* Check for bare parameter packs in the member variable declaration. */
if (TREE_CODE (decl) == FIELD_DECL)
check_for_bare_parameter_packs (&TREE_TYPE (decl));
{
if (check_for_bare_parameter_packs (&TREE_TYPE (decl)))
TREE_TYPE (decl) = error_mark_node;
if (check_for_bare_parameter_packs (&DECL_ATTRIBUTES (decl)))
DECL_ATTRIBUTES (decl) = NULL_TREE;
}
/* [dcl.link]

View File

@ -2351,6 +2351,13 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
*walk_subtrees_p = 0;
break;
case USING_DECL:
WALK_SUBTREE (DECL_NAME (*tp));
WALK_SUBTREE (USING_DECL_SCOPE (*tp));
WALK_SUBTREE (USING_DECL_DECLS (*tp));
*walk_subtrees_p = 0;
break;
case RECORD_TYPE:
if (TYPE_PTRMEMFUNC_P (*tp))
WALK_SUBTREE (TYPE_PTRMEMFUNC_FN_TYPE (*tp));

View File

@ -6642,7 +6642,8 @@ check_return_expr (tree retval, bool *no_warning)
if (processing_template_decl)
{
current_function_returns_value = 1;
check_for_bare_parameter_packs (&retval);
if (check_for_bare_parameter_packs (&retval))
retval = error_mark_node;
return retval;
}

View File

@ -1,3 +1,22 @@
2008-01-15 Douglas Gregor <doug.gregor@gmail.com>
PR c++/34051
PR c++/34055
PR c++/34102
PR c++/34103
* g++.dg/cpp0x/vt-34051-2.C: New.
* g++.dg/cpp0x/vt-34102.C: New.
* g++.dg/cpp0x/vt-34051.C: New.
* g++.dg/cpp0x/vt-34055.C: New.
* g++.dg/cpp0x/vt-34103.C: New.
2008-01-15 Douglas Gregor <doug.gregor@gmail.com>
PR c++/34314
* g++.dg/cpp0x/vt-34314.C: New.
* g++.dg/cpp0x/variadic79.C: Fix the error message to reflect
reality (the error message was wrong previously).
2008-01-15 Douglas Gregor <doug.gregor@gmail.com>
PR c++/33964

View File

@ -0,0 +1,7 @@
// { dg-options "-std=c++0x" }
template<typename... T> struct A
{
int i __attribute__((aligned(__alignof(T)))); // { dg-error "parameter packs|T" }
};
A<int> a;

View File

@ -0,0 +1,12 @@
// { dg-options "-std=c++0x" }
struct A
{
operator int();
};
template <typename... T> struct B : A
{
using A::operator T; // { dg-error "parameter packs|T" }
};
B<int> b;

View File

@ -0,0 +1,10 @@
// { dg-options "-std=c++0x" }
// PR c++/34055
template<typename...> struct A; // { dg-error "declaration" }
template<typename...T> struct A<T*> // { dg-error "parameter packs|T" }
{
void foo();
};
template<typename...T> void A<T*>::foo() {} // { dg-error "invalid use" }

View File

@ -0,0 +1,7 @@
// { dg-options "-std=c++0x" }
// PR c++/34102
struct A {};
template<typename> struct B : virtual A {};
template<typename...T> struct C : B<T> {}; // { dg-error "parameter packs|T" }

View File

@ -0,0 +1,7 @@
// { dg-options "-std=c++0x" }
// PR c++/34103
template<typename> struct A {};
template<typename...T> void foo(A<T>, A<T>); // { dg-error "parameter packs|T" }
template<typename...T> void foo(A<T>, A<T>) {} // { dg-error "parameter packs|T" }