Commit 4439d02f by Douglas Gregor Committed by Doug Gregor

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
parent a022041e
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
* error.c (dump_simple_decl): Display ellipsis for template
non-type parameter packs.
......
......@@ -11748,6 +11748,10 @@ cp_parser_using_declaration (cp_parser* parser,
{
/* Create the USING_DECL. */
decl = do_class_using_decl (parser->scope, identifier);
if (check_for_bare_parameter_packs (&decl))
return false;
else
/* Add it to the list of members in this class. */
finish_member_declaration (decl);
}
......@@ -11756,6 +11760,8 @@ cp_parser_using_declaration (cp_parser* parser,
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,12 +15269,14 @@ 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));
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);
/* If it's not a comma, then the list is complete. */
......
......@@ -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)
......
......@@ -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]
......
......@@ -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));
......
......@@ -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;
}
......
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
* g++.dg/cpp0x/vt-33964.C: New.
* g++.dg/template/partial5.C: New.
// { dg-options "-std=c++0x" }
template<typename... T> struct A
{
int i __attribute__((aligned(__alignof(T)))); // { dg-error "parameter packs|T" }
};
A<int> a;
// { 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;
// { 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" }
// { 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" }
// { 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" }
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