On 12/8/20 4:23 AM, Jakub Jelinek wrote:
Hi!

The earlier cases in build_new_1 already use | tf_no_cleanup, these are
cases where the type isn't type_build_ctor_call nor explicit_value_init_p.
It is true that often one can't delete these (unless e.g. the dtor would be
private or protected and deletion done in some method), but diagnosing that
belongs to delete, not new.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?

It wasn't clear to me why adding tf_no_cleanup in those places made a difference; after some investigation I tried moving the tf_no_cleanup closer to where we build a TARGET_EXPR and then soon put it in an INIT_EXPR.

I also added an array-new to the testcase.

Tested x86_64-linux.  Does make sense to you?
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 0b98f338feb..3c3e05d9b21 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -1922,7 +1922,7 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
 	   in an exception region.  */;
       else
 	init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP,
-			    flags, complain);
+			    flags, complain | tf_no_cleanup);
 
       if (TREE_CODE (init) == MUST_NOT_THROW_EXPR)
 	/* We need to protect the initialization of a catch parm with a
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 4d499af5ccb..afbb8ef02e6 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -8860,7 +8860,7 @@ cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode,
        LOOKUP_ONLYCONVERTING.  */
     newrhs = convert_for_initialization (lhs, olhstype, newrhs, LOOKUP_NORMAL,
 					 ICR_INIT, NULL_TREE, 0,
-                                         complain);
+					 complain | tf_no_cleanup);
   else
     newrhs = convert_for_assignment (olhstype, newrhs, ICR_ASSIGN,
 				     NULL_TREE, 0, complain, LOOKUP_IMPLICIT);
diff --git a/gcc/testsuite/g++.dg/cpp0x/new4.C b/gcc/testsuite/g++.dg/cpp0x/new4.C
new file mode 100644
index 00000000000..728ef4ee7ce
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/new4.C
@@ -0,0 +1,36 @@
+// PR c++/59238
+// { dg-do compile { target c++11 } }
+
+struct A { ~A () = delete; };
+A *pa{new A{}};
+A *pa2{new A[2]{}};
+
+class B { ~B () = default; };
+B *pb{new B{}};
+
+struct E {
+  ~E () = delete;
+private:
+  int x;
+};
+E *pe{new E{}};
+
+class C { ~C (); };
+C *pc{new C{}};
+
+class D { ~D () {} };
+D *pd{new D{}};
+
+struct F {
+  F () = default;
+  ~F () = delete;
+};
+F *pf{new F{}};
+
+struct G {
+  G () = default;
+  ~G () = delete;
+private:
+  int x;
+};
+G *pg{new G{}};

Reply via email to