aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDouglas Gregor <doug.gregor@gmail.com>2008-01-15 18:08:00 +0000
committerDoug Gregor <dgregor@gcc.gnu.org>2008-01-15 18:08:00 +0000
commit4439d02f0f5881b186b7d3430a9504310e227e30 (patch)
tree86bf7020da1cd67cb456d3a5b266ad9a0edd947c /gcc
parenta022041e4ca05c32d7d17a26ce6f0716b4ba642f (diff)
downloadgcc-4439d02f0f5881b186b7d3430a9504310e227e30.zip
gcc-4439d02f0f5881b186b7d3430a9504310e227e30.tar.gz
gcc-4439d02f0f5881b186b7d3430a9504310e227e30.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog32
-rw-r--r--gcc/cp/parser.c20
-rw-r--r--gcc/cp/pt.c21
-rw-r--r--gcc/cp/semantics.c24
-rw-r--r--gcc/cp/tree.c7
-rw-r--r--gcc/cp/typeck.c3
-rw-r--r--gcc/testsuite/ChangeLog19
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/vt-34051-2.C7
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/vt-34051.C12
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/vt-34055.C10
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/vt-34102.C7
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/vt-34103.C7
12 files changed, 147 insertions, 22 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 0b6ec64..5325bcd 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,37 @@
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.
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 16f5a4e..1400424 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -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);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index d364b20..57dc8f8 100644
--- a/gcc/cp/pt.c
+++ b/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)
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 0e8c435..8cf9ceb 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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]
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 843f6c4..7459266 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -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));
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 0f7ecf7..50a844a 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -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;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3ae1bd2..10cc27d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,24 @@
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.
diff --git a/gcc/testsuite/g++.dg/cpp0x/vt-34051-2.C b/gcc/testsuite/g++.dg/cpp0x/vt-34051-2.C
new file mode 100644
index 0000000..2c7bb50
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/vt-34051-2.C
@@ -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;
diff --git a/gcc/testsuite/g++.dg/cpp0x/vt-34051.C b/gcc/testsuite/g++.dg/cpp0x/vt-34051.C
new file mode 100644
index 0000000..88ae567
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/vt-34051.C
@@ -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;
diff --git a/gcc/testsuite/g++.dg/cpp0x/vt-34055.C b/gcc/testsuite/g++.dg/cpp0x/vt-34055.C
new file mode 100644
index 0000000..921b813
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/vt-34055.C
@@ -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" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/vt-34102.C b/gcc/testsuite/g++.dg/cpp0x/vt-34102.C
new file mode 100644
index 0000000..00f0b4f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/vt-34102.C
@@ -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" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/vt-34103.C b/gcc/testsuite/g++.dg/cpp0x/vt-34103.C
new file mode 100644
index 0000000..3bbbb46
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/vt-34103.C
@@ -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" }