aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2020-12-08 22:05:45 -0500
committerJason Merrill <jason@redhat.com>2020-12-09 00:36:07 -0500
commit4eb28483004f8291c1f17df3b242716a5151c180 (patch)
tree5c7a70117b394a18685e1d30946071f2b0f7e69e /gcc
parentf6e8e2797ebae21e483373e303ec1c7596309625 (diff)
downloadgcc-4eb28483004f8291c1f17df3b242716a5151c180.zip
gcc-4eb28483004f8291c1f17df3b242716a5151c180.tar.gz
gcc-4eb28483004f8291c1f17df3b242716a5151c180.tar.bz2
c++: Don't require accessible dtors for some forms of new [PR59238]
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/init.c2
-rw-r--r--gcc/cp/typeck.c2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/new4.C36
3 files changed, 38 insertions, 2 deletions
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 0b98f33..3c3e05d 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 4d499af..afbb8ef 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 0000000..728ef4e
--- /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{}};