aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2008-07-31 13:38:08 -0400
committerJason Merrill <jason@gcc.gnu.org>2008-07-31 13:38:08 -0400
commit10ee5386adadefebd247c7e4870c666f2c9b359d (patch)
tree8faf9acdedf5f85f81f9b4f164dc21693c231eb4 /gcc
parentfc74cbc4bd40b9f1b0f58abff1fb9efecb5b1d49 (diff)
downloadgcc-10ee5386adadefebd247c7e4870c666f2c9b359d.zip
gcc-10ee5386adadefebd247c7e4870c666f2c9b359d.tar.gz
gcc-10ee5386adadefebd247c7e4870c666f2c9b359d.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/init.c40
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/new1.C42
3 files changed, 68 insertions, 18 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f01593d..db536e4 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 5535033..c6d63b8 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -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);
diff --git a/gcc/testsuite/g++.dg/tree-ssa/new1.C b/gcc/testsuite/g++.dg/tree-ssa/new1.C
new file mode 100644
index 0000000..a859f0a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/new1.C
@@ -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" } } */