Jakub noticed that in build_new_1 we needed to add tf_no_cleanup to avoid
building a cleanup for a TARGET_EXPR that we already know is going to be
used to initialize something, so the cleanup will never be run. The best
place to add it is close to where we build the INIT_EXPR; in
cp_build_modify_expr fixes the single-object new, in expand_default_init
fixes array new.
Co-authored-by: Jakub Jelinek <jakub@redhat.com>
gcc/cp/ChangeLog:
PR c++/59238
* init.c (expand_default_init): Pass tf_no_cleanup when building
a TARGET_EXPR to go on the RHS of an INIT_EXPR.
* typeck.c (cp_build_modify_expr): Likewise.
gcc/testsuite/ChangeLog:
PR c++/59238
* g++.dg/cpp0x/new4.C: New test.
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
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);
--- /dev/null
+// 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{}};