mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-21 15:40:55 +08:00
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:
parent
a022041e4c
commit
4439d02f0f
@ -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
|
||||
|
@ -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);
|
||||
|
21
gcc/cp/pt.c
21
gcc/cp/pt.c
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
7
gcc/testsuite/g++.dg/cpp0x/vt-34051-2.C
Normal file
7
gcc/testsuite/g++.dg/cpp0x/vt-34051-2.C
Normal 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;
|
12
gcc/testsuite/g++.dg/cpp0x/vt-34051.C
Normal file
12
gcc/testsuite/g++.dg/cpp0x/vt-34051.C
Normal 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;
|
10
gcc/testsuite/g++.dg/cpp0x/vt-34055.C
Normal file
10
gcc/testsuite/g++.dg/cpp0x/vt-34055.C
Normal 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" }
|
7
gcc/testsuite/g++.dg/cpp0x/vt-34102.C
Normal file
7
gcc/testsuite/g++.dg/cpp0x/vt-34102.C
Normal 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" }
|
7
gcc/testsuite/g++.dg/cpp0x/vt-34103.C
Normal file
7
gcc/testsuite/g++.dg/cpp0x/vt-34103.C
Normal 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" }
|
Loading…
x
Reference in New Issue
Block a user