Commit a6111661 by Jason Merrill Committed by Jason Merrill

init.c (build_new_1): Preevaluate placement args.

        * init.c (build_new_1): Preevaluate placement args.
        * call.c (build_op_delete_call): Don't expose placement args to
        overload resolution.

From-SVN: r73677
parent 47fcfa7b
2003-11-17 Jason Merrill <jason@redhat.com>
* init.c (build_new_1): Preevaluate placement args.
* call.c (build_op_delete_call): Don't expose placement args to
overload resolution.
2003-11-16 Jason Merrill <jason@redhat.com> 2003-11-16 Jason Merrill <jason@redhat.com>
* Make-lang.in (c++.tags): Create TAGS.sub files in each directory * Make-lang.in (c++.tags): Create TAGS.sub files in each directory
......
...@@ -3824,10 +3824,6 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, ...@@ -3824,10 +3824,6 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
/* Find the allocation function that is being called. */ /* Find the allocation function that is being called. */
call_expr = placement; call_expr = placement;
/* Sometimes we have a COMPOUND_EXPR, rather than a simple
CALL_EXPR. */
while (TREE_CODE (call_expr) == COMPOUND_EXPR)
call_expr = TREE_OPERAND (call_expr, 1);
/* Extract the function. */ /* Extract the function. */
alloc_fn = get_callee_fndecl (call_expr); alloc_fn = get_callee_fndecl (call_expr);
my_friendly_assert (alloc_fn != NULL_TREE, 20020327); my_friendly_assert (alloc_fn != NULL_TREE, 20020327);
...@@ -3910,7 +3906,15 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, ...@@ -3910,7 +3906,15 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
args = tree_cons (NULL_TREE, addr, args = tree_cons (NULL_TREE, addr,
build_tree_list (NULL_TREE, size)); build_tree_list (NULL_TREE, size));
return build_function_call (fn, args); if (placement)
{
/* The placement args might not be suitable for overload
resolution at this point, so build the call directly. */
mark_used (fn);
return build_cxx_call (fn, args, args);
}
else
return build_function_call (fn, args);
} }
/* If we are doing placement delete we do nothing if we don't find a /* If we are doing placement delete we do nothing if we don't find a
......
...@@ -2060,13 +2060,22 @@ build_new_1 (tree exp) ...@@ -2060,13 +2060,22 @@ build_new_1 (tree exp)
if (alloc_call == error_mark_node) if (alloc_call == error_mark_node)
return error_mark_node; return error_mark_node;
/* The ALLOC_CALL should be a CALL_EXPR -- or a COMPOUND_EXPR whose /* In the simple case, we can stop now. */
right-hand-side is ultimately a CALL_EXPR -- and the first pointer_type = build_pointer_type (type);
operand should be the address of a known FUNCTION_DECL. */ if (!cookie_size && !is_initialized)
t = alloc_call; return build_nop (pointer_type, alloc_call);
while (TREE_CODE (t) == COMPOUND_EXPR)
t = TREE_OPERAND (t, 1); /* While we're working, use a pointer to the type we've actually
alloc_fn = get_callee_fndecl (t); allocated. Store the result of the call in a variable so that we
can use it more than once. */
full_pointer_type = build_pointer_type (full_type);
alloc_expr = get_target_expr (build_nop (full_pointer_type, alloc_call));
alloc_node = TARGET_EXPR_SLOT (alloc_expr);
/* Strip any COMPOUND_EXPRs from ALLOC_CALL. */
while (TREE_CODE (alloc_call) == COMPOUND_EXPR)
alloc_call = TREE_OPERAND (alloc_call, 1);
alloc_fn = get_callee_fndecl (alloc_call);
my_friendly_assert (alloc_fn != NULL_TREE, 20020325); my_friendly_assert (alloc_fn != NULL_TREE, 20020325);
/* Now, check to see if this function is actually a placement /* Now, check to see if this function is actually a placement
...@@ -2083,6 +2092,27 @@ build_new_1 (tree exp) ...@@ -2083,6 +2092,27 @@ build_new_1 (tree exp)
= (type_num_arguments (TREE_TYPE (alloc_fn)) > 1 = (type_num_arguments (TREE_TYPE (alloc_fn)) > 1
|| varargs_function_p (alloc_fn)); || varargs_function_p (alloc_fn));
/* Preevaluate the placement args so that we don't reevaluate them for a
placement delete. */
if (placement_allocation_fn_p)
{
tree inits = NULL_TREE;
t = TREE_CHAIN (TREE_OPERAND (alloc_call, 1));
for (; t; t = TREE_CHAIN (t))
if (TREE_SIDE_EFFECTS (TREE_VALUE (t)))
{
tree init;
TREE_VALUE (t) = stabilize_expr (TREE_VALUE (t), &init);
if (inits)
inits = build (COMPOUND_EXPR, void_type_node, inits, init);
else
inits = init;
}
if (inits)
alloc_expr = build (COMPOUND_EXPR, TREE_TYPE (alloc_expr), inits,
alloc_expr);
}
/* unless an allocation function is declared with an empty excep- /* unless an allocation function is declared with an empty excep-
tion-specification (_except.spec_), throw(), it indicates failure to tion-specification (_except.spec_), throw(), it indicates failure to
allocate storage by throwing a bad_alloc exception (clause _except_, allocate storage by throwing a bad_alloc exception (clause _except_,
...@@ -2096,18 +2126,6 @@ build_new_1 (tree exp) ...@@ -2096,18 +2126,6 @@ build_new_1 (tree exp)
nothrow = TYPE_NOTHROW_P (TREE_TYPE (alloc_fn)); nothrow = TYPE_NOTHROW_P (TREE_TYPE (alloc_fn));
check_new = (flag_check_new || nothrow) && ! use_java_new; check_new = (flag_check_new || nothrow) && ! use_java_new;
/* In the simple case, we can stop now. */
pointer_type = build_pointer_type (type);
if (!cookie_size && !is_initialized)
return build_nop (pointer_type, alloc_call);
/* While we're working, use a pointer to the type we've actually
allocated. Store the result of the call in a variable so that we
can use it more than once. */
full_pointer_type = build_pointer_type (full_type);
alloc_expr = get_target_expr (build_nop (full_pointer_type, alloc_call));
alloc_node = TARGET_EXPR_SLOT (alloc_expr);
if (cookie_size) if (cookie_size)
{ {
tree cookie; tree cookie;
......
// { dg-do run }
void* operator new (unsigned int sz, void*) { return operator new (sz); }
void operator delete (void* p, void*) { operator delete (p); }
struct A { A() { throw 1; } };
int c;
void *f() { ++c; return 0; }
int main()
{
try
{
new (f()) A;
}
catch (...) {}
return c != 1;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment