re PR middle-end/36633 (warning "array subscript is below array bounds" on delete [] with -O2, -Wall)

PR c++/36633
        * init.c (build_new_1): Don't convert pointer to the data type
        until we're actually going to treat it as that type.

From-SVN: r138425
This commit is contained in:
Jason Merrill 2008-07-31 13:38:08 -04:00 committed by Jason Merrill
parent fc74cbc4bd
commit 10ee5386ad
3 changed files with 68 additions and 18 deletions

View File

@ -1,5 +1,9 @@
2008-07-31 Jason Merrill <jason@redhat.com>
PR c++/36633
* init.c (build_new_1): Don't convert pointer to the data type
until we're actually going to treat it as that type.
PR c++/11309
* tree.c (build_aggr_init_expr): Split out...
(build_cplus_new): ...from here.

View File

@ -2055,11 +2055,9 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
return rval;
}
/* 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));
/* Store the result of the allocation call in a variable so that we can
use it more than once. */
alloc_expr = get_target_expr (alloc_call);
alloc_node = TARGET_EXPR_SLOT (alloc_expr);
/* Strip any COMPOUND_EXPRs from ALLOC_CALL. */
@ -2111,16 +2109,17 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
tree size_ptr_type;
/* Adjust so we're pointing to the start of the object. */
data_addr = get_target_expr (build2 (POINTER_PLUS_EXPR, full_pointer_type,
alloc_node, cookie_size));
data_addr = build2 (POINTER_PLUS_EXPR, TREE_TYPE (alloc_node),
alloc_node, cookie_size);
/* Store the number of bytes allocated so that we can know how
many elements to destroy later. We use the last sizeof
(size_t) bytes to store the number of elements. */
cookie_ptr = fold_build1 (NEGATE_EXPR, sizetype, size_in_bytes (sizetype));
cookie_ptr = size_binop (MINUS_EXPR, cookie_size, size_in_bytes (sizetype));
cookie_ptr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (alloc_node),
alloc_node, cookie_ptr);
size_ptr_type = build_pointer_type (sizetype);
cookie_ptr = build2 (POINTER_PLUS_EXPR, size_ptr_type,
fold_convert (size_ptr_type, data_addr), cookie_ptr);
cookie_ptr = fold_convert (size_ptr_type, cookie_ptr);
cookie = cp_build_indirect_ref (cookie_ptr, NULL, complain);
cookie_expr = build2 (MODIFY_EXPR, sizetype, cookie, nelts);
@ -2134,11 +2133,10 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
cookie = cp_build_indirect_ref (cookie_ptr, NULL, complain);
cookie = build2 (MODIFY_EXPR, sizetype, cookie,
size_in_bytes(elt_type));
size_in_bytes (elt_type));
cookie_expr = build2 (COMPOUND_EXPR, TREE_TYPE (cookie_expr),
cookie, cookie_expr);
}
data_addr = TARGET_EXPR_SLOT (data_addr);
}
else
{
@ -2146,6 +2144,10 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
data_addr = alloc_node;
}
/* Now use a pointer to the type we've actually allocated. */
full_pointer_type = build_pointer_type (full_type);
data_addr = fold_convert (full_pointer_type, data_addr);
/* Now initialize the allocated object. Note that we preevaluate the
initialization expression, apart from the actual constructor call or
assignment--we do this because we want to delay the allocation as long
@ -2241,11 +2243,13 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
/* The Standard is unclear here, but the right thing to do
is to use the same method for finding deallocation
functions that we use for finding allocation functions. */
cleanup = build_op_delete_call (dcode, alloc_node, size,
globally_qualified_p,
(placement_allocation_fn_p
? alloc_call : NULL_TREE),
alloc_fn);
cleanup = (build_op_delete_call
(dcode,
fold_convert (full_pointer_type, alloc_node),
size,
globally_qualified_p,
placement_allocation_fn_p ? alloc_call : NULL_TREE,
alloc_fn));
if (!cleanup)
/* We're done. */;
@ -2300,7 +2304,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
if (cookie_expr)
rval = build2 (COMPOUND_EXPR, TREE_TYPE (rval), cookie_expr, rval);
if (rval == alloc_node)
if (rval == data_addr)
/* If we don't have an initializer or a cookie, strip the TARGET_EXPR
and return the call (which doesn't need to be adjusted). */
rval = TARGET_EXPR_INITIAL (alloc_expr);

View File

@ -0,0 +1,42 @@
// PR c++/36633
/* { dg-do compile } */
/* { dg-options "-O2 -Wall -fdump-tree-forwprop1" } */
// No particular reason for choosing forwprop1 dump to look at.
struct B { ~B() {} };
struct D : public B {};
//struct D {};
struct my_deleter
{
void operator()(D * d)
{
// delete [] d;
}
};
struct smart_ptr
{
smart_ptr(D * ptr) : p(ptr) { }
~smart_ptr() { d(p); }
D * p;
my_deleter d;
};
int
test01()
{
smart_ptr p(new D[7]);
return 0;
}
int main()
{
test01();
return 0;
}
/* { dg-final { scan-tree-dump-not "= .* \\+ -" "forwprop1" } } */
/* { dg-final { cleanup-tree-dump "forwprop1" } } */