re PR c++/27668 (ICE with invalid template parameter)
authorLee Millward <lee.millward@codesourcery.com>
Fri, 28 Jul 2006 17:01:19 +0000 (17:01 +0000)
committerLee Millward <lmillward@gcc.gnu.org>
Fri, 28 Jul 2006 17:01:19 +0000 (17:01 +0000)
        PR c++/27668
        PR c++/27962
        * pt.c (process_template_parm) Store invalid template
        parameters as error_mark_node in the paramater list.
        (push_inline_template_parms_recursive): Handle invalid
        template parameters.
        (comp_template_parms): Likewise.
        (check_default_tmpl_arg): Likewise.
        (coerce_template_template_parms): Likewise.
        (mangle_class_name_for_template): Likewise.
        (tsubst_template_parms): Likewise.
        * error.c (dump_template_argument_list): Likewise.

        * g++.dg/template/crash55.C: New test.
        * g++.dg/template/nontype16.C: New test.
        * g++.dg/template/void2.C: Adjust error markers.
        * g++.dg/template/nontype5.C: Adjust error markers.

From-SVN: r115800

gcc/cp/ChangeLog
gcc/cp/error.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/crash55.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/nontype16.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/nontype5.C
gcc/testsuite/g++.dg/template/void2.C

index 42db58a80609026a94cd2bebe8f8688d265c9bd9..355332ac26774d54d565aa10a4b8051053535a48 100644 (file)
@@ -1,3 +1,18 @@
+2006-07-28  Lee Millward  <lee.millward@codesourcery.com>
+
+        PR c++/27668
+        PR c++/27962
+        * pt.c (process_template_parm) Store invalid template
+        parameters as error_mark_node in the paramater list.
+        (push_inline_template_parms_recursive): Handle invalid
+        template parameters.
+        (comp_template_parms): Likewise.
+        (check_default_tmpl_arg): Likewise.
+        (coerce_template_template_parms): Likewise.
+        (mangle_class_name_for_template): Likewise.
+        (tsubst_template_parms): Likewise.
+        * error.c (dump_template_argument_list): Likewise.
+       
 2006-07-28  Kazu Hirata  <kazu@codesourcery.com>
 
        * cp-tree.h: Fix a comment typo.
index 91a73cca4fcee6c8eed32478c2acb6fff437b59c..d6c813da7a7f7409e018f6d0a73718c3a53e91aa 100644 (file)
@@ -166,8 +166,14 @@ dump_template_argument_list (tree args, int flags)
 static void
 dump_template_parameter (tree parm, int flags)
 {
-  tree p = TREE_VALUE (parm);
-  tree a = TREE_PURPOSE (parm);
+  tree p;
+  tree a;
+
+  if (parm == error_mark_node)
+   return;
+
+  p = TREE_VALUE (parm);
+  a = TREE_PURPOSE (parm);
 
   if (TREE_CODE (p) == TYPE_DECL)
     {
index 0b852fa2df46452bec50331426b4a24befe79d50..5a7bfb8da551d50686c00e7d57bc86bd4fb08721 100644 (file)
@@ -336,7 +336,12 @@ push_inline_template_parms_recursive (tree parmlist, int levels)
               NULL);
   for (i = 0; i < TREE_VEC_LENGTH (parms); ++i)
     {
-      tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
+      tree parm;
+
+      if (TREE_VEC_ELT (parms, i) == error_mark_node)
+        continue;
+
+      parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
       gcc_assert (DECL_P (parm));
 
       switch (TREE_CODE (parm))
@@ -2204,8 +2209,15 @@ comp_template_parms (tree parms1, tree parms2)
 
       for (i = 0; i < TREE_VEC_LENGTH (t2); ++i)
        {
-         tree parm1 = TREE_VALUE (TREE_VEC_ELT (t1, i));
-         tree parm2 = TREE_VALUE (TREE_VEC_ELT (t2, i));
+          tree parm1;
+          tree parm2;
+
+          if (TREE_VEC_ELT (t1, i) == error_mark_node
+              || TREE_VEC_ELT (t2, i) == error_mark_node)
+            continue;
+
+         parm1 = TREE_VALUE (TREE_VEC_ELT (t1, i));
+          parm2 = TREE_VALUE (TREE_VEC_ELT (t2, i));
 
          if (TREE_CODE (parm1) != TREE_CODE (parm2))
            return 0;
@@ -2362,7 +2374,7 @@ process_template_parm (tree list, tree parm, bool is_non_type)
       SET_DECL_TEMPLATE_PARM_P (parm);
 
       if (TREE_TYPE (parm) == error_mark_node)
-       TREE_TYPE (parm) = void_type_node;
+       return chainon(list, error_mark_node);
       else
       {
        /* [temp.param]
@@ -2371,7 +2383,7 @@ process_template_parm (tree list, tree parm, bool is_non_type)
           ignored when determining its type.  */
        TREE_TYPE (parm) = TYPE_MAIN_VARIANT (TREE_TYPE (parm));
        if (invalid_nontype_parm_type_p (TREE_TYPE (parm), 1))
-         TREE_TYPE (parm) = void_type_node;
+         return chainon(list, error_mark_node);
       }
 
       /* A template parameter is not modifiable.  */
@@ -2838,6 +2850,10 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial)
       for (i = 0; i < ntparms; ++i)
        {
          tree parm = TREE_VEC_ELT (inner_parms, i);
+
+          if (parm == error_mark_node)
+            continue;
+
          if (TREE_PURPOSE (parm))
            seen_def_arg_p = 1;
          else if (seen_def_arg_p)
@@ -2902,18 +2918,23 @@ check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial)
 
       ntparms = TREE_VEC_LENGTH (inner_parms);
       for (i = 0; i < ntparms; ++i)
-       if (TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i)))
-         {
-           if (msg)
-             {
-               error (msg, decl);
-               msg = 0;
-             }
+        {
+          if (TREE_VEC_ELT (inner_parms, i) == error_mark_node)
+            continue;
 
-           /* Clear out the default argument so that we are not
-              confused later.  */
-           TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i)) = NULL_TREE;
-         }
+         if (TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i)))
+           {
+             if (msg)
+               {
+                 error (msg, decl);
+                 msg = 0;
+               }
+
+             /* Clear out the default argument so that we are not
+                confused later.  */
+             TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i)) = NULL_TREE;
+           }
+        }
 
       /* At this point, if we're still interested in issuing messages,
         they must apply to classes surrounding the object declared.  */
@@ -3764,6 +3785,9 @@ coerce_template_template_parms (tree parm_parms,
 
   for (i = 0; i < nparms; ++i)
     {
+      if (TREE_VEC_ELT (parm_parms, i) == error_mark_node)
+        continue;
+
       parm = TREE_VALUE (TREE_VEC_ELT (parm_parms, i));
       arg = TREE_VALUE (TREE_VEC_ELT (arg_parms, i));
 
@@ -4023,7 +4047,8 @@ coerce_template_parms (tree parms,
       || (nargs < nparms
          && require_all_args
          && (!use_default_args
-             || !TREE_PURPOSE (TREE_VEC_ELT (parms, nargs)))))
+             || (TREE_VEC_ELT (parms, nargs) != error_mark_node
+                  && !TREE_PURPOSE (TREE_VEC_ELT (parms, nargs))))))
     {
       if (complain & tf_error)
        {
@@ -4046,6 +4071,9 @@ coerce_template_parms (tree parms,
 
       /* Get the Ith template parameter.  */
       parm = TREE_VEC_ELT (parms, i);
+      if (parm == error_mark_node)
+        continue;
 
       /* Calculate the Ith argument.  */
       if (i < nargs)
@@ -4146,8 +4174,14 @@ mangle_class_name_for_template (const char* name, tree parms, tree arglist)
   gcc_assert (nparms == TREE_VEC_LENGTH (arglist));
   for (i = 0; i < nparms; i++)
     {
-      tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
-      tree arg = TREE_VEC_ELT (arglist, i);
+      tree parm;
+      tree arg;
+
+      if (TREE_VEC_ELT (parms, i) == error_mark_node)
+        continue;
+
+      parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
+      arg = TREE_VEC_ELT (arglist, i);
 
       if (i)
        ccat (',');
@@ -6053,9 +6087,20 @@ tsubst_template_parms (tree parms, tree args, tsubst_flags_t complain)
 
       for (i = 0; i < TREE_VEC_LENGTH (new_vec); ++i)
        {
-         tree tuple = TREE_VEC_ELT (TREE_VALUE (parms), i);
-         tree default_value = TREE_PURPOSE (tuple);
-         tree parm_decl = TREE_VALUE (tuple);
+          tree tuple;
+          tree default_value;
+          tree parm_decl;
+
+          if (parms == error_mark_node)
+            continue;
+
+          tuple = TREE_VEC_ELT (TREE_VALUE (parms), i);
+
+          if (tuple == error_mark_node)
+            continue;
+
+          default_value = TREE_PURPOSE (tuple);
+          parm_decl = TREE_VALUE (tuple);
 
          parm_decl = tsubst (parm_decl, args, complain, NULL_TREE);
          if (TREE_CODE (parm_decl) == PARM_DECL
index 4cfaccf2615bdfbfe154b304d16e2255c6d2d91c..90c9ebf89e32ceb18f2c4cd510d77bfa75e11f42 100644 (file)
@@ -1,3 +1,14 @@
+2006-07-28  Lee Millward  <lee.millward@codesourcery.com>
+
+        PR c++/27668
+        * g++.dg/template/crash55.C: New test.
+
+        PR c++/27962
+        * g++.dg/template/nontype16.C: New test.
+
+        * g++.dg/template/void2.C: Adjust error markers.
+        * g++.dg/template/nontype5.C: Adjust error markers.
+       
 2006-07-27  Arjan van de Ven <arjan@linux.intel.com>
 
        * gcc.target/i386/stack-prot-kernel.c: New test.
diff --git a/gcc/testsuite/g++.dg/template/crash55.C b/gcc/testsuite/g++.dg/template/crash55.C
new file mode 100644 (file)
index 0000000..7e15b66
--- /dev/null
@@ -0,0 +1,6 @@
+//PR c++/27668
+
+template<typename class T, T = T()> // { dg-error "nested-name-specifier|two or more|valid type" }
+struct A {};                        // { dg-error "definition"
+
+template<int> void foo(A<int>);     // { dg-error "mismatch|constant" }
diff --git a/gcc/testsuite/g++.dg/template/nontype16.C b/gcc/testsuite/g++.dg/template/nontype16.C
new file mode 100644 (file)
index 0000000..36d1e95
--- /dev/null
@@ -0,0 +1,9 @@
+//PR c++/27962
+
+template<int> struct A
+{
+    template<typename> void foo();
+};
+
+template<> template<struct T> void A<0>::foo() {} // { dg-error "not a valid type" }
index e53b6c1a6548ac969ae77edd2ca0f05a9d107d6c..f7b76259bbc384f6e97afe1c3829e4240eb74ca2 100644 (file)
@@ -11,4 +11,4 @@ template <int> struct A
     template <B> struct C {};  // { dg-error "not a valid type" }
 };
 
-A<0> a;                                // { dg-error "instantiated" }
+A<0> a;
index aa041783ff8c073aed8b7798f0efae31bdd93db6..05a8186e03a511cec57c7ad9a4c074a395262651 100644 (file)
@@ -6,4 +6,4 @@ template<int> struct A
   template<void> friend class X;  // { dg-error "void" }
 };
 
-A<0> a;  // { dg-error "instantiated" }
+A<0> a;