diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 385398346b06..6789236c031f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,21 @@ +2008-02-15 Douglas Gregor + + PR c++/35023 + PR c++/35024 + PR c++/35026 + * pt.c (finish_member_template_decl): If the type in a TYPE_DECL + is error_mark_node, return an error early. + (find_parameter_packs_r): Pass the pointer set along to recursive + calls of cp_walk_subtrees; don't try to manage the pointer set + ourselves. + (uses_parameter_packs): Pass the pointer set to cp_walk_tree. + (make_pack_expansion): Ditto. + (check_for_bare_parameter_packs): Ditto. Also, don't bother taking + a second pass through the tree with find_parameter_packs_r; that + second pass no longer does anything. + (push_template_decl_real): If we have an erroneous declaration, + set its type to error_mark_node before returning an error. + 2008-02-14 Douglas Gregor PR c++/34050 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index d11a959fba8c..5931126e860b 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -236,6 +236,8 @@ finish_member_template_decl (tree decl) tree type; type = TREE_TYPE (decl); + if (type == error_mark_node) + return error_mark_node; if (IS_AGGR_TYPE (type) && CLASSTYPE_TEMPLATE_INFO (type) && !CLASSTYPE_TEMPLATE_SPECIALIZATION (type)) @@ -2445,13 +2447,6 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data) (struct find_parameter_pack_data*)data; bool parameter_pack_p = false; - /* Don't visit nodes twice. */ - if (pointer_set_contains (ppd->visited, *tp)) - { - *walk_subtrees = 0; - return NULL_TREE; - } - /* Identify whether this is a parameter pack or not. */ switch (TREE_CODE (t)) { @@ -2487,12 +2482,9 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data) *ppd->parameter_packs = tree_cons (NULL_TREE, t, *ppd->parameter_packs); } - /* Make sure we do not visit this node again. */ - pointer_set_insert (ppd->visited, *tp); - if (TYPE_P (t)) cp_walk_tree (&TYPE_CONTEXT (t), - &find_parameter_packs_r, ppd, NULL); + &find_parameter_packs_r, ppd, ppd->visited); /* This switch statement will return immediately if we don't find a parameter pack. */ @@ -2504,10 +2496,10 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data) case BOUND_TEMPLATE_TEMPLATE_PARM: /* Check the template itself. */ cp_walk_tree (&TREE_TYPE (TYPE_TI_TEMPLATE (t)), - &find_parameter_packs_r, ppd, NULL); + &find_parameter_packs_r, ppd, ppd->visited); /* Check the template arguments. */ cp_walk_tree (&TYPE_TI_ARGS (t), &find_parameter_packs_r, ppd, - NULL); + ppd->visited); *walk_subtrees = 0; return NULL_TREE; @@ -2527,19 +2519,19 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data) case ENUMERAL_TYPE: if (TYPE_TEMPLATE_INFO (t)) cp_walk_tree (&TREE_VALUE (TYPE_TEMPLATE_INFO (t)), - &find_parameter_packs_r, ppd, NULL); + &find_parameter_packs_r, ppd, ppd->visited); *walk_subtrees = 0; return NULL_TREE; case TEMPLATE_DECL: cp_walk_tree (&TREE_TYPE (t), - &find_parameter_packs_r, ppd, NULL); + &find_parameter_packs_r, ppd, ppd->visited); return NULL_TREE; case TYPENAME_TYPE: cp_walk_tree (&TYPENAME_TYPE_FULLNAME (t), &find_parameter_packs_r, - ppd, NULL); + ppd, ppd->visited); *walk_subtrees = 0; return NULL_TREE; @@ -2550,12 +2542,13 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data) case INTEGER_TYPE: cp_walk_tree (&TYPE_MAX_VALUE (t), &find_parameter_packs_r, - ppd, NULL); + ppd, ppd->visited); *walk_subtrees = 0; return NULL_TREE; case IDENTIFIER_NODE: - cp_walk_tree (&TREE_TYPE (t), &find_parameter_packs_r, ppd, NULL); + cp_walk_tree (&TREE_TYPE (t), &find_parameter_packs_r, ppd, + ppd->visited); *walk_subtrees = 0; return NULL_TREE; @@ -2574,7 +2567,7 @@ uses_parameter_packs (tree t) struct find_parameter_pack_data ppd; ppd.parameter_packs = ¶meter_packs; ppd.visited = pointer_set_create (); - cp_walk_tree (&t, &find_parameter_packs_r, &ppd, NULL); + cp_walk_tree (&t, &find_parameter_packs_r, &ppd, ppd.visited); pointer_set_destroy (ppd.visited); return parameter_packs != NULL_TREE; } @@ -2625,7 +2618,7 @@ make_pack_expansion (tree arg) ppd.visited = pointer_set_create (); ppd.parameter_packs = ¶meter_packs; cp_walk_tree (&TREE_PURPOSE (arg), &find_parameter_packs_r, - &ppd, NULL); + &ppd, ppd.visited); if (parameter_packs == NULL_TREE) { @@ -2643,7 +2636,7 @@ make_pack_expansion (tree arg) /* Determine which parameter packs will be expanded in this argument. */ cp_walk_tree (&TREE_VALUE (value), &find_parameter_packs_r, - &ppd, NULL); + &ppd, ppd.visited); } } @@ -2681,7 +2674,7 @@ make_pack_expansion (tree arg) /* Determine which parameter packs will be expanded. */ ppd.parameter_packs = ¶meter_packs; ppd.visited = pointer_set_create (); - cp_walk_tree (&arg, &find_parameter_packs_r, &ppd, NULL); + cp_walk_tree (&arg, &find_parameter_packs_r, &ppd, ppd.visited); pointer_set_destroy (ppd.visited); /* Make sure we found some parameter packs. */ @@ -2726,7 +2719,7 @@ check_for_bare_parameter_packs (tree t) ppd.parameter_packs = ¶meter_packs; ppd.visited = pointer_set_create (); - cp_walk_tree (&t, &find_parameter_packs_r, &ppd, NULL); + cp_walk_tree (&t, &find_parameter_packs_r, &ppd, ppd.visited); pointer_set_destroy (ppd.visited); if (parameter_packs) @@ -2753,13 +2746,6 @@ check_for_bare_parameter_packs (tree t) parameter_packs = TREE_CHAIN (parameter_packs); } - /* Clean up any references to these parameter packs within the - tree. */ - ppd.parameter_packs = ¶meter_packs; - ppd.visited = pointer_set_create (); - cp_walk_tree (&t, &find_parameter_packs_r, &ppd, NULL); - pointer_set_destroy (ppd.visited); - return true; } @@ -3887,7 +3873,10 @@ push_template_decl_real (tree decl, bool is_friend) TYPE_RAISES_EXCEPTIONS (type) = NULL_TREE; } else if (check_for_bare_parameter_packs (TREE_TYPE (decl))) - return error_mark_node; + { + TREE_TYPE (decl) = error_mark_node; + return error_mark_node; + } if (is_partial) return process_partial_specialization (decl); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0b888ea8d714..6665d266314a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2008-02-15 Douglas Gregor + + PR c++/35023 + PR c++/35024 + PR c++/35026 + * g++.dg/cpp0x/vt-35026.C: New. + * g++.dg/cpp0x/vt-35023.C: New. + * g++.dg/cpp0x/vt-34055.C: Tweak expected error messages. + * g++.dg/cpp0x/vt-35024.C: New. + 2008-02-15 Uros Bizjak * gcc.c-torture/execute/va-arg-25.x: Remove. diff --git a/gcc/testsuite/g++.dg/cpp0x/vt-34055.C b/gcc/testsuite/g++.dg/cpp0x/vt-34055.C index 8ad9c2d52661..29066b50bd72 100644 --- a/gcc/testsuite/g++.dg/cpp0x/vt-34055.C +++ b/gcc/testsuite/g++.dg/cpp0x/vt-34055.C @@ -7,7 +7,7 @@ template struct A // { dg-error "parameter packs|T" } void foo(); // { dg-error "parameter packs|T|candidate" } }; -template void A::foo() {} // { dg-error "does not match" } +template void A::foo() {} // { dg-error "invalid declarator" } @@ -18,7 +18,7 @@ template struct B // { dg-error "parameter packs|T" } void foo(); // { dg-error "parameter packs|T" } }; -template void B::foo() {} // { dg-error "does not match" } +template void B::foo() {} // { dg-error "invalid declarator" } template struct C; @@ -28,4 +28,4 @@ template struct C // { dg-error "parameter packs|T" } void foo(); // { dg-error "parameter packs|T" } }; -template void C::foo() {} // { dg-error "does not match" } +template void C::foo() {} // { dg-error "invalid declarator" } diff --git a/gcc/testsuite/g++.dg/cpp0x/vt-35023.C b/gcc/testsuite/g++.dg/cpp0x/vt-35023.C new file mode 100644 index 000000000000..9db20503e7ef --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/vt-35023.C @@ -0,0 +1,11 @@ +// { dg-options "-std=c++0x" } +template int foo() +{ + T t; // { dg-error "parameter packs|T" } + return t; +} + +void bar() +{ + foo(); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/vt-35024.C b/gcc/testsuite/g++.dg/cpp0x/vt-35024.C new file mode 100644 index 000000000000..77f0b66bdc02 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/vt-35024.C @@ -0,0 +1,11 @@ +// { dg-options "-std=c++0x" } +template int foo() +{ + typename T::X x; // { dg-error "parameter packs|T" } + return x; +} + +void bar() +{ + foo(); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/vt-35026.C b/gcc/testsuite/g++.dg/cpp0x/vt-35026.C new file mode 100644 index 000000000000..643a416c5787 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/vt-35026.C @@ -0,0 +1,7 @@ +// { dg-options "-std=c++0x" } +template struct A +{ + T* x[1]; // { dg-error "parameter packs|T" } +}; + +A a;