Hi,
as far as I can see this ICE on invalid points to a substantive, if
minor, weakness of our implementation of the destroying operator delete
facility: we aren't implementing the bits, per 7.6.2.5/(10.1), about
destroying operator delete having precedence over any other operator
delete. Thus the below, which is the most straightforward implementation
I have been able to figure out given the current infrastructure. Tested
x86_64-linux.
Thanks, Paolo.
////////////////////
/cp
2019-01-24 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/88969
* call.c (build_op_delete_call): Implement 7.6.2.5/(10.1).
/testsuite
2019-01-24 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/88969
* g++.dg/cpp2a/destroying-delete2.C: New.
Index: cp/call.c
===================================================================
--- cp/call.c (revision 268234)
+++ cp/call.c (working copy)
@@ -6461,6 +6461,19 @@ build_op_delete_call (enum tree_code code, tree ad
continue;
}
+ /* -- If any of the deallocation functions is a destroying
+ operator delete, all deallocation functions that are not
+ destroying operator deletes are eliminated from further
+ consideration. */
+ bool fn_destroying = destroying_delete_p (fn);
+ bool elt_destroying = destroying_delete_p (elt);
+ if (elt_destroying != fn_destroying)
+ {
+ if (elt_destroying)
+ fn = elt;
+ continue;
+ }
+
/* -- If the type has new-extended alignment, a function with a
parameter of type std::align_val_t is preferred; otherwise a
function without such a parameter is preferred. If exactly one
Index: testsuite/g++.dg/cpp2a/destroying-delete2.C
===================================================================
--- testsuite/g++.dg/cpp2a/destroying-delete2.C (nonexistent)
+++ testsuite/g++.dg/cpp2a/destroying-delete2.C (working copy)
@@ -0,0 +1,20 @@
+// PR c++/88969
+// { dg-do compile { target c++2a } }
+
+#include <new>
+
+namespace delete_selection_d {
+ struct B {
+ void operator delete(void*) = delete;
+ void operator delete(B *, std::destroying_delete_t) = delete; // {
dg-message "declared here" }
+ };
+ void delete_B(B *b) { delete b; } // { dg-error "use of deleted function" }
+}
+
+namespace delete_selection_r {
+ struct B {
+ void operator delete(B *, std::destroying_delete_t) = delete; // {
dg-message "declared here" }
+ void operator delete(void*) = delete;
+ };
+ void delete_B(B *b) { delete b; } // { dg-error "use of deleted function" }
+}