re PR c++/28736 (ICE with friend of invalid template class)
authorLee Millward <lee.millward@codesourcery.com>
Sat, 26 Aug 2006 17:41:18 +0000 (17:41 +0000)
committerLee Millward <lmillward@gcc.gnu.org>
Sat, 26 Aug 2006 17:41:18 +0000 (17:41 +0000)
        PR c++/28736
        PR c++/28737
        PR c++/28738
        * pt.c (process_template_parm): Store invalid template
        parameters as a TREE_LIST with a TREE_VALUE of error_mark_node.
        (push_inline_template_parms_recursive): Check for template
        parameters having a TREE_VALUE of error_mark_node rather than
        check the parameter itself.
        (mangle_class_name_for_template): Likewise.
        (comp_template_parms): When comparing the individual template
        parameters, return 1 if either is error_mark_node.
        (current_template_args): Robustify.
        (redeclare_class_template): Likewise.

        * g++.dg/template/void10.C: New test.
        * g++.dg/template/void8.C: New test.
        * g++.dg/template/void9.C: New test.

        * g++.dg/template/void3.C: Adjust error markers.
        * g++.dg/template/void4.C: Likewise.
        * g++.dg/template/crash55.C: Likewise.
        * g++.dg/template/void7.C: Likewise.

From-SVN: r116473

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/crash55.C
gcc/testsuite/g++.dg/template/void10.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/void3.C
gcc/testsuite/g++.dg/template/void4.C
gcc/testsuite/g++.dg/template/void7.C
gcc/testsuite/g++.dg/template/void8.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/void9.C [new file with mode: 0644]

index d7c952dd8804352bad65eae25554acc110847914..e219547c545c0f4c553cbe62d4a7efbc9d61cdd4 100644 (file)
@@ -1,3 +1,19 @@
+2006-08-26  Lee Millward  <lee.millward@codesourcery.com>
+
+        PR c++/28736
+        PR c++/28737
+        PR c++/28738
+        * pt.c (process_template_parm): Store invalid template
+        parameters as a TREE_LIST with a TREE_VALUE of error_mark_node.
+        (push_inline_template_parms_recursive): Check for template
+        parameters having a TREE_VALUE of error_mark_node rather than
+        check the parameter itself.
+        (mangle_class_name_for_template): Likewise.
+        (comp_template_parms): When comparing the individual template
+        parameters, return 1 if either is error_mark_node.
+        (current_template_args): Robustify.
+        (redeclare_class_template): Likewise.
+       
 2006-08-26  Mark Mitchell  <mark@codesourcery.com>
 
        PR c++/28588
index e078149fa770fd91aa6af355bff1ed9f556ddee5..5e0c9541b9a7194f1cc58d2f40c291e0fedf69b3 100644 (file)
@@ -336,12 +336,11 @@ push_inline_template_parms_recursive (tree parmlist, int levels)
               NULL);
   for (i = 0; i < TREE_VEC_LENGTH (parms); ++i)
     {
-      tree parm;
+      tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
 
-      if (TREE_VEC_ELT (parms, i) == error_mark_node)
-        continue;
+      if (parm == error_mark_node)
+       continue;
 
-      parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
       gcc_assert (DECL_P (parm));
 
       switch (TREE_CODE (parm))
@@ -2212,15 +2211,13 @@ comp_template_parms (tree parms1, tree parms2)
 
       for (i = 0; i < TREE_VEC_LENGTH (t2); ++i)
        {
-          tree parm1;
-          tree parm2;
+          tree parm1 = TREE_VALUE (TREE_VEC_ELT (t1, i));
+          tree parm2 = TREE_VALUE (TREE_VEC_ELT (t2, i));
 
-          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 either of the template parameters are invalid, assume
+             they match for the sake of error recovery. */
+          if (parm1 == error_mark_node || parm2 == error_mark_node)
+            return 1;
 
          if (TREE_CODE (parm1) != TREE_CODE (parm2))
            return 0;
@@ -2352,6 +2349,7 @@ process_template_parm (tree list, tree parm, bool is_non_type)
 {
   tree decl = 0;
   tree defval;
+  tree err_parm_list;
   int idx = 0;
 
   gcc_assert (TREE_CODE (parm) == TREE_LIST);
@@ -2361,7 +2359,7 @@ process_template_parm (tree list, tree parm, bool is_non_type)
     {
       tree p = tree_last (list);
 
-      if (p && p != error_mark_node)
+      if (p && TREE_VALUE (p) != error_mark_node)
         {
           p = TREE_VALUE (p);
           if (TREE_CODE (p) == TYPE_DECL || TREE_CODE (p) == TEMPLATE_DECL)
@@ -2382,7 +2380,11 @@ process_template_parm (tree list, tree parm, bool is_non_type)
       SET_DECL_TEMPLATE_PARM_P (parm);
 
       if (TREE_TYPE (parm) == error_mark_node)
-       return chainon(list, error_mark_node);
+        {
+          err_parm_list = build_tree_list (defval, parm);
+          TREE_VALUE (err_parm_list) = error_mark_node;
+          return chainon (list, err_parm_list);
+        }
       else
       {
        /* [temp.param]
@@ -2391,7 +2393,11 @@ 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))
-         return chainon(list, error_mark_node);
+          {
+            err_parm_list = build_tree_list (defval, parm);
+            TREE_VALUE (err_parm_list) = error_mark_node;
+            return chainon (list, err_parm_list);
+          }
       }
 
       /* A template parameter is not modifiable.  */
@@ -2522,11 +2528,15 @@ current_template_args (void)
            {
              t = TREE_VALUE (t);
 
-             if (TREE_CODE (t) == TYPE_DECL
-                 || TREE_CODE (t) == TEMPLATE_DECL)
-               t = TREE_TYPE (t);
-             else
-               t = DECL_INITIAL (t);
+             if (t != error_mark_node)
+               {
+                 if (TREE_CODE (t) == TYPE_DECL
+                     || TREE_CODE (t) == TEMPLATE_DECL)
+                   t = TREE_TYPE (t);
+                 else
+                   t = DECL_INITIAL (t);
+               }
+
              TREE_VEC_ELT (a, i) = t;
            }
        }
@@ -3350,9 +3360,10 @@ redeclare_class_template (tree type, tree parms)
 
       /* TMPL_PARM and PARM can be either TYPE_DECL, PARM_DECL, or
         TEMPLATE_DECL.  */
-      if (TREE_CODE (tmpl_parm) != TREE_CODE (parm)
-         || (TREE_CODE (tmpl_parm) != TYPE_DECL
-             && !same_type_p (TREE_TYPE (tmpl_parm), TREE_TYPE (parm))))
+      if (tmpl_parm != error_mark_node
+          && (TREE_CODE (tmpl_parm) != TREE_CODE (parm)
+          || (TREE_CODE (tmpl_parm) != TYPE_DECL
+              && !same_type_p (TREE_TYPE (tmpl_parm), TREE_TYPE (parm)))))
        {
          error ("template parameter %q+#D", tmpl_parm);
          error ("redeclared here as %q#D", parm);
@@ -4207,12 +4218,12 @@ mangle_class_name_for_template (const char* name, tree parms, tree arglist)
       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 (parm == error_mark_node)
+       continue;
+
       if (i)
        ccat (',');
 
index 017de891864a60557eb002ced2671f41e68ebe8b..1df799676b4b389198df2e2c352424960accd95f 100644 (file)
@@ -1,3 +1,19 @@
+2006-08-26  Lee Millward  <lee.millward@codesourcery.com>
+
+        PR c++/28736
+        * g++.dg/template/void10.C: New test.
+
+        PR c++/28737
+        * g++.dg/template/void8.C: New test.
+
+        PR c+_+/28738
+        * g++.dg/template/void9.C: New test.
+
+        * g++.dg/template/void3.C: Adjust error markers.
+        * g++.dg/template/void4.C: Likewise.
+        * g++.dg/template/crash55.C: Likewise.
+        * g++.dg/template/void7.C: Likewise
+       
 2006-08-26  Mark Mitchell  <mark@codesourcery.com>
 
        PR c++/28588
index 7e15b66ee75b0e28b81bb36233b932989bbeb111..0e3fe4c3a5939b8e1a314d9d719ab0bceb995ae9 100644 (file)
@@ -3,4 +3,4 @@
 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" }
+template<int> void foo(A<int>);     // { dg-error "mismatch|constant|template argument" }
diff --git a/gcc/testsuite/g++.dg/template/void10.C b/gcc/testsuite/g++.dg/template/void10.C
new file mode 100644 (file)
index 0000000..56e0b6d
--- /dev/null
@@ -0,0 +1,10 @@
+//PR c++/28736
+
+template<void> struct A                 // { dg-error "not a valid type" }
+{
+    template<typename> friend struct B;
+};
+
+template<typename> struct B {};
+
+B<int> b;                              // { dg-error "template argument|invalid type" }
index 6526a2a47be1db3ebe1421a8e70457a8bad4b7e8..bb59934ffe4f7703b28e9ed153c8e71e443d59a1 100644 (file)
@@ -1,5 +1,5 @@
 //PR c++/28637
 
 template<void> struct A {};  // { dg-error "not a valid type" }
-A<0> a;
+A<0> a;                      // { dg-error "type" }
 
index 7d264fbf10bc47670d38aa04d23284f61bc2f171..fe30b2e3736bcdb76dac9fc82b771760de39b4ab 100644 (file)
@@ -4,4 +4,4 @@ template<void> struct A;  // { dg-error "not a valid type" }
 
 template<template<int> class> struct B {};
 
-B<A> b;
+B<A> b;                  // { dg-error "template|invalid type" }
index 2c464b3a055cfb27870d120e244240e9722c4e3d..95d87a2073220dbcd608dcb6a38fa7cbcf9ea8bd 100644 (file)
@@ -5,4 +5,4 @@ template<void> struct A         // { dg-error "not a valid type" }
   static int i;
 };
 
-A<0> a;
+A<0> a;                        // { dg-error "invalid type|not a valid type" }
diff --git a/gcc/testsuite/g++.dg/template/void8.C b/gcc/testsuite/g++.dg/template/void8.C
new file mode 100644 (file)
index 0000000..e45c91c
--- /dev/null
@@ -0,0 +1,7 @@
+//PR c++/28737
+
+template<void> struct A;                // { dg-error "not a valid type" }
+
+template<typename> struct B;
+
+template<void N> struct B<A<N> > {};   // { dg-error "not a valid type|declared|invalid" }
diff --git a/gcc/testsuite/g++.dg/template/void9.C b/gcc/testsuite/g++.dg/template/void9.C
new file mode 100644 (file)
index 0000000..bb2ed66
--- /dev/null
@@ -0,0 +1,4 @@
+//PR c++/28738
+
+template<int,void> struct A {};    // { dg-error "not a valid type" }
+template<int N> struct A<N,0> {};  // { dg-error "not a valid type" }