]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/34051 (ICE in dependent_type_p with variadic templates)
authorDouglas Gregor <doug.gregor@gmail.com>
Tue, 15 Jan 2008 18:08:00 +0000 (18:08 +0000)
committerDoug Gregor <dgregor@gcc.gnu.org>
Tue, 15 Jan 2008 18:08:00 +0000 (18:08 +0000)
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

12 files changed:
gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/cp/tree.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/vt-34051-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/vt-34051.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/vt-34055.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/vt-34102.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/vt-34103.C [new file with mode: 0644]

index 0b6ec64b5efae8c0654e121a6175fb355adef98b..5325bcdd24c4a6f6fc44309ee6c57117722e433a 100644 (file)
@@ -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
index 16f5a4e4c06518350d12b23b1abe681922618232..1400424c2fff470dc7ea76cb57c9045f5eb85e00 100644 (file)
@@ -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);
index d364b20e9c568d03d0aa2e4a1c47296f3dacf7fd..57dc8f86766bd7b86d6874a73ca0741a85090453 100644 (file)
@@ -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)
index 0e8c435dcc8bea46fec36e7cf39a7f56cdd07ada..8cf9ceba3890eea6e0689115dbac919fc8e69a38 100644 (file)
@@ -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]
 
index 843f6c45590cf17ffead22155d03ba5a873d8333..7459266d43ab71025c5f451f75a9c1f19cc057ef 100644 (file)
@@ -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));
index 0f7ecf723a48be6220095e6a5d1ae7c426d764fe..50a844a95e0e0bec31b6e74c26b9a0dfb51d0210 100644 (file)
@@ -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;
     }
 
index 3ae1bd2ff1d4a806677f0251d0a202ac3cbb74cc..10cc27d779287f6deb18078402f5f5d7e80145bf 100644 (file)
@@ -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
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 (file)
index 0000000..2c7bb50
--- /dev/null
@@ -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 (file)
index 0000000..88ae567
--- /dev/null
@@ -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 (file)
index 0000000..921b813
--- /dev/null
@@ -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 (file)
index 0000000..00f0b4f
--- /dev/null
@@ -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 (file)
index 0000000..3bbbb46
--- /dev/null
@@ -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" }