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>();