This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [C++ PATCH] Fix variadic templates regressions on mainline
- From: "Doug Gregor" <doug dot gregor at gmail dot com>
- To: "GCC Patches" <gcc-patches at gcc dot gnu dot org>, "Jason Merrill" <jason at redhat dot com>
- Date: Mon, 28 Jan 2008 19:00:22 -0500
- Subject: Re: [C++ PATCH] Fix variadic templates regressions on mainline
- References: <24b520d20801281425o29b9429frb77e7134f1fb2840@mail.gmail.com>
Whoops, hold the presses. Turns out that with three new lines of code
this also fixes PR c++/34219. PR c++/34753, PR c++/34754, and PR
c++/34755 are also all fixed by this patch. So, here's the final
patch, which fixes 9 (!) regressions due to poor error-recovery in the
handling of variadic templates.
Tested i686-pc-linux-gnu; okay for mainline?
- Doug
2008-01-28 Douglas Gregor <doug.gregor@gmail.com>
PR c++/34055
PR c++/34103
PR c++/34219
PR c++/34606
PR c++/34753
PR c++/34754
PR c++/34755
PR c++/34919
PR c++/34961
* c-pretty-print.c (pp_c_type_qualifier_list): Don't try to print
qualifiers for an ERROR_MARK_NODE or a NULL_TREE.
2008-01-28 Douglas Gregor <doug.gregor@gmail.com>
PR c++/34055
PR c++/34103
PR c++/34219
PR c++/34606
PR c++/34753
PR c++/34754
PR c++/34755
PR c++/34919
PR c++/34961
* typeck.c (check_return_expr): Tweak call to
check_for_bare_parameter_packs.
* class.c (add_method): Be careful with error_mark_nodes.
* cp-tree.h (check_for_bare_parameter_packs): Remove "*" from
signature.
* pt.c (struct find_parameter_pack_data): Remove
SET_PACKS_TO_ERROR.
(find_parameter_packs_r): Don't use SET_PACKS_TO_ERROR.
(uses_parameter_packs): Don't set SET_PACKS_TO_ERROR.
(make_pack_expansion): Ditto.
(check_for_bare_parameter_packs): Parameter is now a tree, not a
tree*.
(process_template_parm): Tweak call to
check_for_bare_parameter_packs.
(push_template_decl_real): Tweak calls to
check_for_bare_parameter_packs. If bare parameter packs are found
in the list of exceptions, clear out that list after giving an
error.
* semantics.c (finish_cond): Tweak call to
check_for_bare_parameter_packs.
(finish_expr_stmt): Ditto.
(finish_for_expr): Ditto.
(finish_switch_cond): Ditto.
(finish_mem_initializers): Ditto.
(finish_member_declaration): Ditto.
(finish_static_assert): Check for bare parameter packs in the
condition.
* decl2.c (cplus_decl_attributes): Check for bare parameter packs in the
attributes of a declaration.
* parser.c (cp_parser_using_declaration): Tweak call to
check_for_bare_parameter_packs.
(cp_parser_base_clause): Ditto.
2008-01-28 Douglas Gregor <doug.gregor@gmail.com>
PR c++/34055
PR c++/34103
PR c++/34219
PR c++/34606
PR c++/34753
PR c++/34754
PR c++/34755
PR c++/34919
PR c++/34961
* g++.dg/cpp0x/vt-34219-2.C: New.
* g++.dg/cpp0x/pr32126.C: Tweak expected error messages.
* g++.dg/cpp0x/vt-34961.C: New.
* g++.dg/cpp0x/vt-34055.C: Tweak error messages; add new test
cases from the re-opened PR.
* g++.dg/cpp0x/vt-34753.C: New.
* g++.dg/cpp0x/vt-34919.C: New.
* g++.dg/cpp0x/vt-34754.C: New.
* g++.dg/cpp0x/vt-34606.C: New.
* g++.dg/cpp0x/vt-34219.C: New.
* g++.dg/cpp0x/pr32125.C: Tweak expected error messages.
* g++.dg/cpp0x/vt-34755.C: New.
* g++.dg/cpp0x/pr31438.C: Ditto.
* g++.dg/cpp0x/variadic81.C: Ditto.
On Mon, Jan 28, 2008 at 5:25 PM, Doug Gregor <doug.gregor@gmail.com> wrote:
> This patch fixes a few outstanding regressions regarding error
> recovery and diagnostics with variadic templates. The most important
> part of this patch reverts my attempt to deal with ill-formed "bare"
> parameter packs by turning them into error_mark_nodes, which caused
> the persistent failure of vt-34103.C on some platforms. This patch
> fixes that problem, and with a few tiny tweaks clears out 4 other
> similar regressions.
>
> Tested i686-pc-linux-gnu. Okay for mainline?
>
> - Doug
>
> 2008-01-28 Douglas Gregor <doug.gregor@gmail.com>
>
> PR c++/34055
> PR c++/34103
> PR c++/34606
> PR c++/34919
> PR c++/34961
> * c-pretty-print.c (pp_c_type_qualifier_list): Don't try to print
> qualifiers for an ERROR_MARK_NODE or a NULL_TREE.
>
>
> 2008-01-28 Douglas Gregor <doug.gregor@gmail.com>
>
> PR c++/34055
> PR c++/34103
> PR c++/34606
> PR c++/34919
> PR c++/34961
> * typeck.c (check_return_expr): Tweak call to
> check_for_bare_parameter_packs.
> * class.c (add_method): Be careful with error_mark_nodes.
> * cp-tree.h (check_for_bare_parameter_packs): Remove "*" from
> signature.
> * pt.c (struct find_parameter_pack_data): Remove
> SET_PACKS_TO_ERROR.
> (find_parameter_packs_r): Don't use SET_PACKS_TO_ERROR.
> (uses_parameter_packs): Don't set SET_PACKS_TO_ERROR.
> (make_pack_expansion): Ditto.
> (check_for_bare_parameter_packs): Parameter is now a tree, not a
> tree*.
> (process_template_parm): Tweak call to
> check_for_bare_parameter_packs.
> (push_template_decl_real): Tweak calls to
> check_for_bare_parameter_packs. If bare parameter packs are found
> in the list of exceptions, clear out that list after giving an
> error.
> * semantics.c (finish_cond): Tweak call to
> check_for_bare_parameter_packs.
> (finish_expr_stmt): Ditto.
> (finish_for_expr): Ditto.
> (finish_switch_cond): Ditto.
> (finish_mem_initializers): Ditto.
> (finish_mem_initializers): Ditto.
> (cplus_decl_attributes): Check for bare parameter packs in the
> attributes of a declaration.
> * parser.c (cp_parser_using_declaration): Tweak call to
> check_for_bare_parameter_packs.
> (cp_parser_base_clause): Ditto.
>
>
> 2008-01-28 Douglas Gregor <doug.gregor@gmail.com>
>
> PR c++/34055
> PR c++/34103
> PR c++/34606
> PR c++/34919
> PR c++/34961
> * g++.dg/cpp0x/pr32126.C: Tweak expected error messages.
> * g++.dg/cpp0x/vt-34961.C: New.
> * g++.dg/cpp0x/vt-34055.C: Tweak error messages; add new test
> cases from the re-opened PR.
> * g++.dg/cpp0x/vt-34919.C: New.
> * g++.dg/cpp0x/vt-34606.C: New.
> * g++.dg/cpp0x/pr32125.C: Tweak expected error messages.
> * g++.dg/cpp0x/pr31438.C: Ditto.
> * g++.dg/cpp0x/variadic81.C: Ditto.
>
Index: c-pretty-print.c
===================================================================
--- c-pretty-print.c (revision 131920)
+++ c-pretty-print.c (working copy)
@@ -225,7 +225,10 @@ pp_c_space_for_pointer_operator (c_prett
void
pp_c_type_qualifier_list (c_pretty_printer *pp, tree t)
{
- int qualifiers;
+ int qualifiers;
+
+ if (!t || t == error_mark_node)
+ return;
if (!TYPE_P (t))
t = TREE_TYPE (t);
Index: cp/typeck.c
===================================================================
--- cp/typeck.c (revision 131920)
+++ cp/typeck.c (working copy)
@@ -6605,7 +6605,7 @@ check_return_expr (tree retval, bool *no
if (processing_template_decl)
{
current_function_returns_value = 1;
- if (check_for_bare_parameter_packs (&retval))
+ if (check_for_bare_parameter_packs (retval))
retval = error_mark_node;
return retval;
}
Index: cp/class.c
===================================================================
--- cp/class.c (revision 131920)
+++ cp/class.c (working copy)
@@ -1035,6 +1035,8 @@ add_method (tree type, tree method, tree
coming from the using class in overload resolution. */
if (! DECL_STATIC_FUNCTION_P (fn)
&& ! DECL_STATIC_FUNCTION_P (method)
+ && TREE_TYPE (TREE_VALUE (parms1)) != error_mark_node
+ && TREE_TYPE (TREE_VALUE (parms2)) != error_mark_node
&& (TYPE_QUALS (TREE_TYPE (TREE_VALUE (parms1)))
!= TYPE_QUALS (TREE_TYPE (TREE_VALUE (parms2)))))
continue;
Index: cp/decl.c
===================================================================
--- cp/decl.c (revision 131920)
+++ cp/decl.c (working copy)
@@ -5388,6 +5388,12 @@ cp_finish_decl (tree decl, tree init, bo
type_dependent_p = dependent_type_p (type);
+ if (check_for_bare_parameter_packs (init))
+ {
+ init = NULL_TREE;
+ DECL_INITIAL (decl) = NULL_TREE;
+ }
+
if (init && init_const_expr_p)
{
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = 1;
Index: cp/cp-tree.h
===================================================================
--- cp/cp-tree.h (revision 131920)
+++ cp/cp-tree.h (working copy)
@@ -4435,7 +4435,7 @@ extern int comp_template_parms (const_
extern bool uses_parameter_packs (tree);
extern bool template_parameter_pack_p (const_tree);
extern tree make_pack_expansion (tree);
-extern bool check_for_bare_parameter_packs (tree*);
+extern bool check_for_bare_parameter_packs (tree);
extern tree get_template_info (tree);
extern int template_class_depth (tree);
extern int is_specialization_of (tree, tree);
Index: cp/pt.c
===================================================================
--- cp/pt.c (revision 131920)
+++ cp/pt.c (working copy)
@@ -2434,10 +2434,6 @@ struct find_parameter_pack_data
/* Set of AST nodes that have been visited by the traversal. */
struct pointer_set_t *visited;
-
- /* Whether we should replace parameter packs with
- ERROR_MARK_NODE. Used by check_for_bare_parameter_packs. */
- bool set_packs_to_error;
};
/* Identifies all of the argument packs that occur in a template
@@ -2452,15 +2448,13 @@ find_parameter_packs_r (tree *tp, int *w
(struct find_parameter_pack_data*)data;
bool parameter_pack_p = false;
- /* Don't visit nodes twice, except when we're clearing out parameter
- packs. */
+ /* Don't visit nodes twice. */
if (pointer_set_contains (ppd->visited, *tp))
{
*walk_subtrees = 0;
return NULL_TREE;
}
-recheck:
/* Identify whether this is a parameter pack or not. */
switch (TREE_CODE (t))
{
@@ -2485,16 +2479,6 @@ recheck:
}
break;
- case POINTER_TYPE:
- if (ppd->set_packs_to_error)
- /* Pointer types are shared, set in that case the outermost
- POINTER_TYPE to error_mark_node rather than the parameter pack. */
- {
- t = TREE_TYPE (t);
- goto recheck;
- }
- break;
-
default:
/* Not a parameter pack. */
break;
@@ -2504,19 +2488,10 @@ recheck:
{
/* Add this parameter pack to the list. */
*ppd->parameter_packs = tree_cons (NULL_TREE, t, *ppd->parameter_packs);
-
- if (ppd->set_packs_to_error)
- /* The caller requested that we set the parameter packs to
- ERROR_MARK_NODE so that they will not trip up the compiler
- later. The caller is responsible for emitting an error. */
- *tp = error_mark_node;
- else
- /* Make sure we do not visit this node again. */
- pointer_set_insert (ppd->visited, *tp);
}
- else
- /* Make sure we do not visit this node again. */
- pointer_set_insert (ppd->visited, *tp);
+
+ /* 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),
@@ -2602,7 +2577,6 @@ uses_parameter_packs (tree t)
struct find_parameter_pack_data ppd;
ppd.parameter_packs = ¶meter_packs;
ppd.visited = pointer_set_create ();
- ppd.set_packs_to_error = false;
cp_walk_tree (&t, &find_parameter_packs_r, &ppd, NULL);
pointer_set_destroy (ppd.visited);
return parameter_packs != NULL_TREE;
@@ -2621,8 +2595,6 @@ make_pack_expansion (tree arg)
bool for_types = false;
struct find_parameter_pack_data ppd;
- ppd.set_packs_to_error = false;
-
if (!arg || arg == error_mark_node)
return arg;
@@ -2744,21 +2716,20 @@ make_pack_expansion (tree arg)
Returns TRUE and emits an error if there were bare parameter packs,
returns FALSE otherwise. */
bool
-check_for_bare_parameter_packs (tree* t)
+check_for_bare_parameter_packs (tree t)
{
tree parameter_packs = NULL_TREE;
struct find_parameter_pack_data ppd;
- if (!processing_template_decl || !t || !*t || *t == error_mark_node)
+ if (!processing_template_decl || !t || t == error_mark_node)
return false;
- if (TREE_CODE (*t) == TYPE_DECL)
- t = &TREE_TYPE (*t);
+ if (TREE_CODE (t) == TYPE_DECL)
+ t = TREE_TYPE (t);
ppd.parameter_packs = ¶meter_packs;
ppd.visited = pointer_set_create ();
- ppd.set_packs_to_error = false;
- cp_walk_tree (t, &find_parameter_packs_r, &ppd, NULL);
+ cp_walk_tree (&t, &find_parameter_packs_r, &ppd, NULL);
pointer_set_destroy (ppd.visited);
if (parameter_packs)
@@ -2789,8 +2760,7 @@ check_for_bare_parameter_packs (tree* t)
tree. */
ppd.parameter_packs = ¶meter_packs;
ppd.visited = pointer_set_create ();
- ppd.set_packs_to_error = true;
- cp_walk_tree (t, &find_parameter_packs_r, &ppd, NULL);
+ cp_walk_tree (&t, &find_parameter_packs_r, &ppd, NULL);
pointer_set_destroy (ppd.visited);
return true;
@@ -3055,7 +3025,7 @@ process_template_parm (tree list, tree p
{
/* This template parameter is not a parameter pack, but it
should be. Complain about "bare" parameter packs. */
- check_for_bare_parameter_packs (&TREE_TYPE (parm));
+ check_for_bare_parameter_packs (TREE_TYPE (parm));
/* Recover by calling this a parameter pack. */
is_parameter_pack = true;
@@ -3895,7 +3865,7 @@ push_template_decl_real (tree decl, bool
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
@@ -3911,14 +3881,15 @@ push_template_decl_real (tree decl, bool
/* 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));
+ if (check_for_bare_parameter_packs (TYPE_RAISES_EXCEPTIONS (type)))
+ TYPE_RAISES_EXCEPTIONS (type) = NULL_TREE;
}
- 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)
Index: cp/semantics.c
===================================================================
--- cp/semantics.c (revision 131920)
+++ cp/semantics.c (working copy)
@@ -508,7 +508,7 @@ finish_cond (tree *cond_p, tree expr)
if (TREE_CODE (cond) == DECL_EXPR)
expr = cond;
- if (check_for_bare_parameter_packs (&expr))
+ if (check_for_bare_parameter_packs (expr))
*cond_p = error_mark_node;
}
*cond_p = expr;
@@ -619,7 +619,7 @@ finish_expr_stmt (tree expr)
else if (!type_dependent_expression_p (expr))
convert_to_void (build_non_dependent_expr (expr), "statement");
- if (check_for_bare_parameter_packs (&expr))
+ if (check_for_bare_parameter_packs (expr))
expr = error_mark_node;
/* Simplification of inner statement expressions, compound exprs,
@@ -877,7 +877,7 @@ finish_for_expr (tree expr, tree for_stm
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);
- if (check_for_bare_parameter_packs (&expr))
+ if (check_for_bare_parameter_packs (expr))
expr = error_mark_node;
FOR_EXPR (for_stmt) = expr;
}
@@ -974,7 +974,7 @@ finish_switch_cond (tree cond, tree swit
cond = index;
}
}
- if (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;
@@ -1393,7 +1393,7 @@ finish_mem_initializers (tree mem_inits)
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)))
+ && check_for_bare_parameter_packs (TREE_VALUE (mem)))
TREE_VALUE (mem) = error_mark_node;
}
@@ -2331,9 +2331,9 @@ finish_member_declaration (tree decl)
/* Check for bare parameter packs in the member variable declaration. */
if (TREE_CODE (decl) == FIELD_DECL)
{
- if (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)))
+ if (check_for_bare_parameter_packs (DECL_ATTRIBUTES (decl)))
DECL_ATTRIBUTES (decl) = NULL_TREE;
}
@@ -4025,6 +4025,9 @@ void
finish_static_assert (tree condition, tree message, location_t location,
bool member_p)
{
+ if (check_for_bare_parameter_packs (condition))
+ condition = error_mark_node;
+
if (type_dependent_expression_p (condition)
|| value_dependent_expression_p (condition))
{
Index: cp/decl2.c
===================================================================
--- cp/decl2.c (revision 131920)
+++ cp/decl2.c (working copy)
@@ -1107,6 +1107,9 @@ cplus_decl_attributes (tree *decl, tree
if (processing_template_decl)
{
+ if (check_for_bare_parameter_packs (attributes))
+ return;
+
save_template_attributes (&attributes, decl);
if (attributes == NULL_TREE)
return;
Index: cp/parser.c
===================================================================
--- cp/parser.c (revision 131920)
+++ cp/parser.c (working copy)
@@ -11776,7 +11776,7 @@ cp_parser_using_declaration (cp_parser*
/* Create the USING_DECL. */
decl = do_class_using_decl (parser->scope, identifier);
- if (check_for_bare_parameter_packs (&decl))
+ if (check_for_bare_parameter_packs (decl))
return false;
else
/* Add it to the list of members in this class. */
@@ -11787,7 +11787,7 @@ cp_parser_using_declaration (cp_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))
+ else if (check_for_bare_parameter_packs (decl))
return false;
else if (!at_namespace_scope_p ())
do_local_using_decl (decl, qscope, identifier);
@@ -15327,7 +15327,7 @@ cp_parser_base_clause (cp_parser* parser
TREE_VALUE (base) = make_pack_expansion (TREE_VALUE (base));
- if (!check_for_bare_parameter_packs (&TREE_VALUE (base)))
+ if (!check_for_bare_parameter_packs (TREE_VALUE (base)))
{
TREE_CHAIN (base) = bases;
bases = base;
Index: testsuite/g++.dg/cpp0x/vt-34219-2.C
===================================================================
--- testsuite/g++.dg/cpp0x/vt-34219-2.C (revision 0)
+++ testsuite/g++.dg/cpp0x/vt-34219-2.C (revision 0)
@@ -0,0 +1,22 @@
+// { dg-options "-std=c++0x" }
+template<template<typename... T> class Comp, typename... T> void f( T... Value)
+{
+ static_assert( Comp<T>::value > 0, "" ); // { dg-error "parameter packs|T" }
+}
+
+template<template<typename... T> class Comp, typename... T> void g( T... Value)
+{
+ static_assert( Comp<T...>::value > 0, "" );
+}
+
+template <typename... T>
+struct Foo
+{
+ static const int value=1;
+};
+
+int main()
+{
+ f<Foo>( 2 );
+ g<Foo>( 2 );
+}
Index: testsuite/g++.dg/cpp0x/pr32126.C
===================================================================
--- testsuite/g++.dg/cpp0x/pr32126.C (revision 131920)
+++ testsuite/g++.dg/cpp0x/pr32126.C (working copy)
@@ -1,8 +1,8 @@
// { dg-options "-std=c++0x" }
template<typename...> struct A;
-template<typename...T> struct A<T> // { dg-error "not expanded|T|not used|T" }
-{
+template<typename...T> struct A<T> // { dg-error "not expanded|T|" }
+{ // { dg-error "not expanded|T|" }
static int i;
};
Index: testsuite/g++.dg/cpp0x/vt-34961.C
===================================================================
--- testsuite/g++.dg/cpp0x/vt-34961.C (revision 0)
+++ testsuite/g++.dg/cpp0x/vt-34961.C (revision 0)
@@ -0,0 +1,7 @@
+// { dg-options "-std=c++0x" }
+template<typename... T> struct A
+{
+ static const int i __attribute__((aligned(__alignof(T)))) = 0; // { dg-error "not expanded|T" }
+};
+
+A<int> a;
Index: testsuite/g++.dg/cpp0x/vt-34055.C
===================================================================
--- testsuite/g++.dg/cpp0x/vt-34055.C (revision 131920)
+++ testsuite/g++.dg/cpp0x/vt-34055.C (working copy)
@@ -1,10 +1,31 @@
// { dg-options "-std=c++0x" }
// PR c++/34055
-template<typename...> struct A; // { dg-error "declaration" }
+template<typename...> struct A;
template<typename...T> struct A<T*> // { dg-error "parameter packs|T" }
-{
- void foo();
+{ // { dg-error "parameter packs|T" }
+ void foo(); // { dg-error "parameter packs|T|candidate" }
};
-template<typename...T> void A<T*>::foo() {} // { dg-error "invalid use" }
+template<typename...T> void A<T*>::foo() {} // { dg-error "does not match" }
+
+
+
+template<typename...> struct B;
+
+template<typename...T> struct B<T&> // { dg-error "parameter packs|T" }
+{ // { dg-error "parameter packs|T" }
+ void foo(); // { dg-error "parameter packs|T" }
+};
+
+template<typename...T> void B<T&>::foo() {} // { dg-error "does not match" }
+
+
+template<typename...> struct C;
+
+template<typename...T> struct C<T()> // { dg-error "parameter packs|T" }
+{ // { dg-error "parameter packs|T" }
+ void foo(); // { dg-error "parameter packs|T" }
+};
+
+template<typename...T> void C<T()>::foo() {} // { dg-error "does not match" }
Index: testsuite/g++.dg/cpp0x/vt-34753.C
===================================================================
--- testsuite/g++.dg/cpp0x/vt-34753.C (revision 0)
+++ testsuite/g++.dg/cpp0x/vt-34753.C (revision 0)
@@ -0,0 +1,14 @@
+// { dg-options "-std=c++0x" }
+template<typename... T> struct A
+{
+ template<T> struct B {}; // { dg-error "not expanded|T" }
+};
+
+A<int>::B<0> b;
+
+template<typename... T> struct B
+{
+ template<T> B(); // { dg-error "not expanded|T" }
+};
+
+B<int> c;
Index: testsuite/g++.dg/cpp0x/vt-34919.C
===================================================================
--- testsuite/g++.dg/cpp0x/vt-34919.C (revision 0)
+++ testsuite/g++.dg/cpp0x/vt-34919.C (revision 0)
@@ -0,0 +1,13 @@
+// { dg-options "-std=c++0x" }
+template<int... N> struct A
+{
+ static void foo()
+ {
+ int i = N; // { dg-error "not expanded|N" }
+ }
+};
+
+void bar()
+{
+ A<0>::foo();
+}
Index: testsuite/g++.dg/cpp0x/vt-34754.C
===================================================================
--- testsuite/g++.dg/cpp0x/vt-34754.C (revision 0)
+++ testsuite/g++.dg/cpp0x/vt-34754.C (revision 0)
@@ -0,0 +1,6 @@
+// { dg-options "-std=c++0x" }
+template<template<int> class... T> struct A
+{
+ void foo(T<0>); // { dg-error "not expanded|T" }
+ void bar(T<0>); // { dg-error "not expanded|T" }
+};
Index: testsuite/g++.dg/cpp0x/vt-34606.C
===================================================================
--- testsuite/g++.dg/cpp0x/vt-34606.C (revision 0)
+++ testsuite/g++.dg/cpp0x/vt-34606.C (revision 0)
@@ -0,0 +1,9 @@
+// { dg-options "-std=c++0x" }
+template<typename...> struct A;
+
+template<typename T, typename... U> struct A<T, U> // { dg-error "parameter packs|U" }
+{ // { dg-error "parameter packs|U" }
+ template<typename> struct B;
+
+ template<typename X> struct B<X*> {}; // { dg-error "parameter packs|U" }
+};
Index: testsuite/g++.dg/cpp0x/vt-34219.C
===================================================================
--- testsuite/g++.dg/cpp0x/vt-34219.C (revision 0)
+++ testsuite/g++.dg/cpp0x/vt-34219.C (revision 0)
@@ -0,0 +1,15 @@
+// { dg-options "-std=c++0x" }
+template<typename T, T a, T... Params>
+struct max
+{
+ static const T value = a > max<T, Params>::value ? a : max<T, Params>::value; // { dg-error "not expanded|Params" }
+};
+
+template<typename T, T a, T b>
+struct max<T, a, b>
+{
+ static const T value = a > b ? a : b;
+};
+
+static const int value1 = max< int, 1, 2>::value;
+static const int value2 = max< int, 1, 3, 5>::value;
Index: testsuite/g++.dg/cpp0x/pr32125.C
===================================================================
--- testsuite/g++.dg/cpp0x/pr32125.C (revision 131920)
+++ testsuite/g++.dg/cpp0x/pr32125.C (working copy)
@@ -1,8 +1,8 @@
// { dg-options "-std=c++0x" }
template<typename...> struct A;
-template<typename...T> struct A<T*> // { dg-error "not expanded|T|not used|T" }
-{
- A();
+template<typename...T> struct A<T*> // { dg-error "not expanded|T" }
+{ // { dg-error "not expanded|T" }
+ A(); // { dg-error "not expanded|T" }
A(T); // { dg-error "not expanded|T" }
};
Index: testsuite/g++.dg/cpp0x/vt-34755.C
===================================================================
--- testsuite/g++.dg/cpp0x/vt-34755.C (revision 0)
+++ testsuite/g++.dg/cpp0x/vt-34755.C (revision 0)
@@ -0,0 +1,6 @@
+// { dg-options "-std=c++0x" }
+template<typename> struct A {};
+
+template<template<typename> class... T> void foo(T<int>) {} // { dg-error "not expanded|T" }
+
+template void foo<A>(A<int>); // { dg-error "does not match" }
Index: testsuite/g++.dg/cpp0x/pr31438.C
===================================================================
--- testsuite/g++.dg/cpp0x/pr31438.C (revision 131920)
+++ testsuite/g++.dg/cpp0x/pr31438.C (working copy)
@@ -1,9 +1,9 @@
// { dg-options "-std=gnu++0x" }
template<typename> struct A;
-template<typename T, typename... U> struct A<T(U)> // { dg-error "parameter packs|U|not used|U" }
-{
- template<typename X> A(X);
+template<typename T, typename... U> struct A<T(U)> // { dg-error "parameter packs|U" }
+{ // { dg-error "parameter packs|U" }
+ template<typename X> A(X); // { dg-error "parameter packs|U" }
};
A<void(int)> a(0); // { dg-error "incomplete type" }
Index: testsuite/g++.dg/cpp0x/variadic81.C
===================================================================
--- testsuite/g++.dg/cpp0x/variadic81.C (revision 131920)
+++ testsuite/g++.dg/cpp0x/variadic81.C (working copy)
@@ -4,7 +4,7 @@
template<typename> struct A;
template<typename... T> struct A<T*> // { dg-error "not expanded|T|not used|T" }
-{
+{ // { dg-error "not expanded|T|not used|T" }
struct B;
};