aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2020-10-02 09:00:49 +0200
committerRichard Biener <rguenther@suse.de>2020-10-02 11:22:20 +0200
commit4f4ced28826ece7b7b76649522ee2a9601a63b90 (patch)
tree4fe85bc7a6d70681537bfe2d93b32fbd39ad5a8c /gcc/cp
parent0b945f959f03a6185a3130f30bfd524d01d4142c (diff)
downloadgcc-4f4ced28826ece7b7b76649522ee2a9601a63b90.zip
gcc-4f4ced28826ece7b7b76649522ee2a9601a63b90.tar.gz
gcc-4f4ced28826ece7b7b76649522ee2a9601a63b90.tar.bz2
c++: Set CALL_FROM_NEW_OR_DELETE_P on more calls.
We were failing to set the flag on a delete call in a new expression, in a deleting destructor, and in a coroutine. Fixed by setting it in the function that builds the call. 2020-10-02 Jason Merril <jason@redhat.com> gcc/cp/ChangeLog: * call.c (build_operator_new_call): Set CALL_FROM_NEW_OR_DELETE_P. (build_op_delete_call): Likewise. * init.c (build_new_1, build_vec_delete_1, build_delete): Not here. (build_delete): gcc/ChangeLog: * gimple.h (gimple_call_operator_delete_p): Rename from gimple_call_replaceable_operator_delete_p. * gimple.c (gimple_call_operator_delete_p): Likewise. * tree.h (DECL_IS_REPLACEABLE_OPERATOR_DELETE_P): Remove. * tree-ssa-dce.c (mark_all_reaching_defs_necessary_1): Adjust. (propagate_necessity): Likewise. (eliminate_unnecessary_stmts): Likewise. * tree-ssa-structalias.c (find_func_aliases_for_call): Likewise. gcc/testsuite/ChangeLog: * g++.dg/pr94314.C: new/delete no longer omitted.
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/call.c29
-rw-r--r--gcc/cp/init.c14
2 files changed, 24 insertions, 19 deletions
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index d67e8fe..bd66251 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -4769,7 +4769,16 @@ build_operator_new_call (tree fnname, vec<tree, va_gc> **args,
*fn = cand->fn;
/* Build the CALL_EXPR. */
- return build_over_call (cand, LOOKUP_NORMAL, complain);
+ tree ret = build_over_call (cand, LOOKUP_NORMAL, complain);
+
+ /* Set this flag for all callers of this function. In addition to
+ new-expressions, this is called for allocating coroutine state; treat
+ that as an implicit new-expression. */
+ tree call = extract_call_expr (ret);
+ if (TREE_CODE (call) == CALL_EXPR)
+ CALL_FROM_NEW_OR_DELETE_P (call) = 1;
+
+ return ret;
}
/* Build a new call to operator(). This may change ARGS. */
@@ -6146,7 +6155,7 @@ build_new_op_1 (const op_location_t &loc, enum tree_code code, int flags,
case VEC_NEW_EXPR:
case VEC_DELETE_EXPR:
case DELETE_EXPR:
- /* Use build_op_new_call and build_op_delete_call instead. */
+ /* Use build_operator_new_call and build_op_delete_call instead. */
gcc_unreachable ();
case CALL_EXPR:
@@ -6983,6 +6992,7 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
if (DECL_DELETED_FN (fn) && alloc_fn)
return NULL_TREE;
+ tree ret;
if (placement)
{
/* The placement args might not be suitable for overload
@@ -6995,7 +7005,7 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
argarray[i] = CALL_EXPR_ARG (placement, i);
if (!mark_used (fn, complain) && !(complain & tf_error))
return error_mark_node;
- return build_cxx_call (fn, nargs, argarray, complain);
+ ret = build_cxx_call (fn, nargs, argarray, complain);
}
else
{
@@ -7013,7 +7023,6 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
complain);
}
- tree ret;
releasing_vec args;
args->quick_push (addr);
if (destroying)
@@ -7026,8 +7035,18 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
args->quick_push (al);
}
ret = cp_build_function_call_vec (fn, &args, complain);
- return ret;
}
+
+ /* Set this flag for all callers of this function. In addition to
+ delete-expressions, this is called for deallocating coroutine state;
+ treat that as an implicit delete-expression. This is also called for
+ the delete if the constructor throws in a new-expression, and for a
+ deleting destructor (which implements a delete-expression). */
+ tree call = extract_call_expr (ret);
+ if (TREE_CODE (call) == CALL_EXPR)
+ CALL_FROM_NEW_OR_DELETE_P (call) = 1;
+
+ return ret;
}
/* [expr.new]
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index e84e985..00fff3f 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -3433,10 +3433,6 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
}
}
- tree alloc_call_expr = extract_call_expr (alloc_call);
- if (TREE_CODE (alloc_call_expr) == CALL_EXPR)
- CALL_FROM_NEW_OR_DELETE_P (alloc_call_expr) = 1;
-
if (cookie_size)
alloc_call = maybe_wrap_new_for_constexpr (alloc_call, elt_type,
cookie_size);
@@ -4145,10 +4141,6 @@ build_vec_delete_1 (location_t loc, tree base, tree maxindex, tree type,
/*placement=*/NULL_TREE,
/*alloc_fn=*/NULL_TREE,
complain);
-
- tree deallocate_call_expr = extract_call_expr (deallocate_expr);
- if (TREE_CODE (deallocate_call_expr) == CALL_EXPR)
- CALL_FROM_NEW_OR_DELETE_P (deallocate_call_expr) = 1;
}
body = loop;
@@ -5073,12 +5065,6 @@ build_delete (location_t loc, tree otype, tree addr,
if (do_delete == error_mark_node)
return error_mark_node;
- else if (do_delete)
- {
- tree do_delete_call_expr = extract_call_expr (do_delete);
- if (TREE_CODE (do_delete_call_expr) == CALL_EXPR)
- CALL_FROM_NEW_OR_DELETE_P (do_delete_call_expr) = 1;
- }
if (do_delete && !TREE_SIDE_EFFECTS (expr))
expr = do_delete;