Hi,

this relatively old bug report is about an ICE during error recovery and some time ago I figured out that the below simple tweak to grokfndecl worked for it (we notice that duplicate_decls returned error_mark_node). Today, however, while formatting the original testcases, I noticed something slightly more interesting: at variance with both current clang and icc, we reject the below deleted6.C, thus we reject explicit instantiations of deleted template functions (without explaining that the function is deleted in the error message and still accepting the code with -fpermissive (?)). Thus the below tweak to instantiate_decl. Without it, 58582 is still fixed of course, only the testcases need a little adjusting.

Tested x86_64-linux.

Thanks,
Paolo.

//////////////////////
Index: cp/decl.c
===================================================================
--- cp/decl.c   (revision 210004)
+++ cp/decl.c   (working copy)
@@ -7822,6 +7822,8 @@ grokfndecl (tree ctype,
                     decl, ctype);
              return NULL_TREE;
            }
+         if (ok == error_mark_node)
+           return NULL_TREE;
          return old_decl;
        }
     }
Index: cp/pt.c
===================================================================
--- cp/pt.c     (revision 210004)
+++ cp/pt.c     (working copy)
@@ -19698,7 +19699,8 @@ instantiate_decl (tree d, int defer_ok,
 
       if (at_eof && !pattern_defined
          && DECL_EXPLICIT_INSTANTIATION (d)
-         && DECL_NOT_REALLY_EXTERN (d))
+         && DECL_NOT_REALLY_EXTERN (d)
+         && (TREE_CODE (d) != FUNCTION_DECL || !DECL_DELETED_FN (d)))
        /* [temp.explicit]
 
           The definition of a non-exported function template, a
Index: testsuite/g++.dg/cpp0x/deleted4.C
===================================================================
--- testsuite/g++.dg/cpp0x/deleted4.C   (revision 0)
+++ testsuite/g++.dg/cpp0x/deleted4.C   (working copy)
@@ -0,0 +1,11 @@
+// PR c++/58582
+// { dg-do compile { target c++11 } }
+
+struct A
+{
+  template<int> void foo() = delete;
+};
+
+template<int> void A::foo() { int i; } // { dg-error "redefinition" }
+
+template void A::foo<0>();
Index: testsuite/g++.dg/cpp0x/deleted5.C
===================================================================
--- testsuite/g++.dg/cpp0x/deleted5.C   (revision 0)
+++ testsuite/g++.dg/cpp0x/deleted5.C   (working copy)
@@ -0,0 +1,11 @@
+// PR c++/58582
+// { dg-do compile { target c++11 } }
+
+struct A
+{
+  template<int> void foo() = delete;
+};
+
+template<int> void A::foo() {} // { dg-error "redefinition" }
+
+template void A::foo<0>();
Index: testsuite/g++.dg/cpp0x/deleted6.C
===================================================================
--- testsuite/g++.dg/cpp0x/deleted6.C   (revision 0)
+++ testsuite/g++.dg/cpp0x/deleted6.C   (working copy)
@@ -0,0 +1,9 @@
+// PR c++/58582
+// { dg-do compile { target c++11 } }
+
+struct A
+{
+  template<int> void foo() = delete;
+};
+
+template void A::foo<0>();

Reply via email to