aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <paolo.carlini@oracle.com>2019-01-25 19:50:55 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2019-01-25 19:50:55 +0000
commit6edee4b3d3a2c970eee897443c9b580ed5d8226b (patch)
treea6397b40fbfb22f832d4ff59be79e34c8c609098
parentf28c46cdb85172eb0e267b97e7a9d3befac30a2e (diff)
downloadgcc-6edee4b3d3a2c970eee897443c9b580ed5d8226b.zip
gcc-6edee4b3d3a2c970eee897443c9b580ed5d8226b.tar.gz
gcc-6edee4b3d3a2c970eee897443c9b580ed5d8226b.tar.bz2
re PR c++/88969 (ICE in build_op_delete_call, at cp/call.c:6509)
/cp 2019-01-25 Paolo Carlini <paolo.carlini@oracle.com> PR c++/88969 * call.c (build_op_delete_call): Implement 7.6.2.5/(10.1). * decl2.c (coerce_delete_type): Use build_pointer_type instead of TYPE_POINTER_TO. /testsuite 2019-01-25 Paolo Carlini <paolo.carlini@oracle.com> PR c++/88969 * g++.dg/cpp2a/destroying-delete2.C: New. * g++.dg/cpp2a/destroying-delete3.C: Likewise. From-SVN: r268278
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/call.c13
-rw-r--r--gcc/cp/decl2.c6
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/destroying-delete2.C20
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/destroying-delete3.C8
6 files changed, 57 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 82a893a..2d7ab90 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2019-01-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/88969
+ * call.c (build_op_delete_call): Implement 7.6.2.5/(10.1).
+ * decl2.c (coerce_delete_type): Use build_pointer_type instead
+ of TYPE_POINTER_TO.
+
2019-01-24 Jason Merrill <jason@redhat.com>
PR c++/89001 - mangling of reference temporaries
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 5bad263..515a942 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -6461,6 +6461,19 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
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
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 5da5beb..72c52e3 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -1757,9 +1757,9 @@ coerce_delete_type (tree decl, location_t loc)
if (destroying_delete_p (decl))
{
if (DECL_CLASS_SCOPE_P (decl))
- /* If the function is a destroying operator delete declared in class type
- C, the type of its first parameter shall be C*. */
- ptrtype = TYPE_POINTER_TO (DECL_CONTEXT (decl));
+ /* If the function is a destroying operator delete declared in class
+ type C, the type of its first parameter shall be C*. */
+ ptrtype = build_pointer_type (DECL_CONTEXT (decl));
else
/* A destroying operator delete shall be a class member function named
operator delete. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 75ce51a..84e195c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2019-01-25 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/88969
+ * g++.dg/cpp2a/destroying-delete2.C: New.
+ * g++.dg/cpp2a/destroying-delete3.C: Likewise.
+
2019-01-25 Steven G. Kargl <kargl@gcc.gnu.org>
PR fortran/85780
diff --git a/gcc/testsuite/g++.dg/cpp2a/destroying-delete2.C b/gcc/testsuite/g++.dg/cpp2a/destroying-delete2.C
new file mode 100644
index 0000000..2592c07
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/destroying-delete2.C
@@ -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" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/destroying-delete3.C b/gcc/testsuite/g++.dg/cpp2a/destroying-delete3.C
new file mode 100644
index 0000000..112fb0a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/destroying-delete3.C
@@ -0,0 +1,8 @@
+// PR c++/88969
+// { dg-do compile { target c++2a } }
+
+#include <new>
+
+struct B {
+ void operator delete(void*, std::destroying_delete_t); // { dg-error ".operator delete. takes type .B*." }
+};