aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/optimize.c
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2016-04-20 19:59:56 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2016-04-20 19:59:56 +0000
commitee392fc2922e9260bf424734f289a23c7be1b899 (patch)
treecc271a4402029d6096a19aed56d717400e6ea923 /gcc/cp/optimize.c
parentdda49daffdfdbb10768cd4b89c7c349d3dd45415 (diff)
downloadgcc-ee392fc2922e9260bf424734f289a23c7be1b899.zip
gcc-ee392fc2922e9260bf424734f289a23c7be1b899.tar.gz
gcc-ee392fc2922e9260bf424734f289a23c7be1b899.tar.bz2
re PR c++/55635 (Deallocation function ("operator delete") not called when destructor throws exception)
cp/ PR c++/55635 * init.c (build_vec_delete_1): Protect operator delete call in try finally. (build_delete): Likewise. * optimize.c (build_delete_destructor_body): Likewise. testsuite/ PR c++/55635 * g++.dg/eh/delete1.C: New. From-SVN: r235297
Diffstat (limited to 'gcc/cp/optimize.c')
-rw-r--r--gcc/cp/optimize.c24
1 files changed, 11 insertions, 13 deletions
diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c
index 6f80b3d..e2032c1 100644
--- a/gcc/cp/optimize.c
+++ b/gcc/cp/optimize.c
@@ -112,26 +112,24 @@ clone_body (tree clone, tree fn, void *arg_map)
static void
build_delete_destructor_body (tree delete_dtor, tree complete_dtor)
{
- tree call_dtor, call_delete;
tree parm = DECL_ARGUMENTS (delete_dtor);
tree virtual_size = cxx_sizeof (current_class_type);
/* Call the corresponding complete destructor. */
gcc_assert (complete_dtor);
- call_dtor = build_cxx_call (complete_dtor, 1, &parm,
- tf_warning_or_error);
- add_stmt (call_dtor);
-
- add_stmt (build_stmt (0, LABEL_EXPR, cdtor_label));
+ tree call_dtor = build_cxx_call (complete_dtor, 1, &parm,
+ tf_warning_or_error);
/* Call the delete function. */
- call_delete = build_op_delete_call (DELETE_EXPR, current_class_ptr,
- virtual_size,
- /*global_p=*/false,
- /*placement=*/NULL_TREE,
- /*alloc_fn=*/NULL_TREE,
- tf_warning_or_error);
- add_stmt (call_delete);
+ tree call_delete = build_op_delete_call (DELETE_EXPR, current_class_ptr,
+ virtual_size,
+ /*global_p=*/false,
+ /*placement=*/NULL_TREE,
+ /*alloc_fn=*/NULL_TREE,
+ tf_warning_or_error);
+
+ /* Operator delete must be called, whether or not the dtor throws. */
+ add_stmt (build2 (TRY_FINALLY_EXPR, void_type_node, call_dtor, call_delete));
/* Return the address of the object. */
if (targetm.cxx.cdtor_returns_this ())