Hi,

On 05/02/2014 08:05 PM, Jason Merrill wrote:
I'd tweak instantiate_decl differently; a deleted function is defined, so pattern_defined should be true.
I see, thanks. Simply setting pattern_defined and nothing else appears to work very well. The only minor annoyance is that DECL_STRUCT_FUNCTION can be null and we have to check for that before using it (in fact, we do that in 2 other places too). Tested x86_64-linux.

Thanks again,
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)
@@ -19616,7 +19617,8 @@ instantiate_decl (tree d, int defer_ok,
 
   if (TREE_CODE (d) == FUNCTION_DECL)
     pattern_defined = (DECL_SAVED_TREE (code_pattern) != NULL_TREE
-                      || DECL_DEFAULTED_OUTSIDE_CLASS_P (code_pattern));
+                      || DECL_DEFAULTED_OUTSIDE_CLASS_P (code_pattern)
+                      || DECL_DELETED_FN (code_pattern));
   else
     pattern_defined = ! DECL_IN_AGGR_P (code_pattern);
 
@@ -19858,14 +19860,17 @@ instantiate_decl (tree d, int defer_ok,
                       tf_warning_or_error, tmpl,
                       /*integral_constant_expression_p=*/false);
 
-         /* Set the current input_location to the end of the function
-            so that finish_function knows where we are.  */
-         input_location
-           = DECL_STRUCT_FUNCTION (code_pattern)->function_end_locus;
+         if (DECL_STRUCT_FUNCTION (code_pattern))
+           {
+             /* Set the current input_location to the end of the function
+                so that finish_function knows where we are.  */
+             input_location
+               = DECL_STRUCT_FUNCTION (code_pattern)->function_end_locus;
 
-         /* Remember if we saw an infinite loop in the template.  */
-         current_function_infinite_loop
-           = DECL_STRUCT_FUNCTION (code_pattern)->language->infinite_loop;
+             /* Remember if we saw an infinite loop in the template.  */
+             current_function_infinite_loop
+               = DECL_STRUCT_FUNCTION (code_pattern)->language->infinite_loop;
+           }
        }
 
       /* We don't need the local specializations any more.  */
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