Commit 10ee5386 by Jason Merrill Committed by Jason Merrill

re PR middle-end/36633 (warning "array subscript is below array bounds" on…

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