re PR c++/88969 (ICE in build_op_delete_call, at cp/call.c:6509)
authorPaolo Carlini <paolo.carlini@oracle.com>
Fri, 25 Jan 2019 19:50:55 +0000 (19:50 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Fri, 25 Jan 2019 19:50:55 +0000 (19:50 +0000)
/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

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/decl2.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp2a/destroying-delete2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp2a/destroying-delete3.C [new file with mode: 0644]

index 82a893ad1701e29f0c5eda6b64a32651a18cda74..2d7ab90885ef1ced15305fed654c43de8632a091 100644 (file)
@@ -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
index 5bad2634cb3b5136e4f7c9f20a47b984e4ac48ec..515a94200324277c842fe1d79afbec5a1493ce01 100644 (file)
@@ -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
index 5da5beb778424729dd9960116b853d89966dd1fc..72c52e39e00d1e4cbeb1ec07095747fa2793b93a 100644 (file)
@@ -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.  */
index 75ce51ad837e0e777c5242001796245e7881e115..84e195cd88d4d50501e6d348ad64b2262e442eb4 100644 (file)
@@ -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 (file)
index 0000000..2592c07
--- /dev/null
@@ -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 (file)
index 0000000..112fb0a
--- /dev/null
@@ -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*." }
+};