Commit 92d38f38 by Florian Weimer Committed by Florian Weimer

init.c (build_new_1): Do not check for arithmetic overflow if inner array size is 1.

	* init.c (build_new_1): Do not check for arithmetic overflow if
	inner array size is 1.

	* g++.dg/init/new40.C: New.

From-SVN: r193287
parent 7d57274b
2012-11-07 Florian Weimer <fweimer@redhat.com>
* init.c (build_new_1): Do not check for arithmetic overflow if
inner array size is 1.
2012-11-05 Sriraman Tallam <tmsriram@google.com> 2012-11-05 Sriraman Tallam <tmsriram@google.com>
* class.c (add_method): Change assembler names of function versions. * class.c (add_method): Change assembler names of function versions.
......
...@@ -2185,6 +2185,8 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts, ...@@ -2185,6 +2185,8 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts,
bool outer_nelts_from_type = false; bool outer_nelts_from_type = false;
double_int inner_nelts_count = double_int_one; double_int inner_nelts_count = double_int_one;
tree alloc_call, alloc_expr; tree alloc_call, alloc_expr;
/* Size of the inner array elements. */
double_int inner_size;
/* The address returned by the call to "operator new". This node is /* The address returned by the call to "operator new". This node is
a VAR_DECL and is therefore reusable. */ a VAR_DECL and is therefore reusable. */
tree alloc_node; tree alloc_node;
...@@ -2346,8 +2348,6 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts, ...@@ -2346,8 +2348,6 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts,
double_int max_size double_int max_size
= double_int_one.llshift (TYPE_PRECISION (sizetype) - 1, = double_int_one.llshift (TYPE_PRECISION (sizetype) - 1,
HOST_BITS_PER_DOUBLE_INT); HOST_BITS_PER_DOUBLE_INT);
/* Size of the inner array elements. */
double_int inner_size;
/* Maximum number of outer elements which can be allocated. */ /* Maximum number of outer elements which can be allocated. */
double_int max_outer_nelts; double_int max_outer_nelts;
tree max_outer_nelts_tree; tree max_outer_nelts_tree;
...@@ -2451,7 +2451,13 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts, ...@@ -2451,7 +2451,13 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts,
if (array_p && TYPE_VEC_NEW_USES_COOKIE (elt_type)) if (array_p && TYPE_VEC_NEW_USES_COOKIE (elt_type))
size = size_binop (PLUS_EXPR, size, cookie_size); size = size_binop (PLUS_EXPR, size, cookie_size);
else else
cookie_size = NULL_TREE; {
cookie_size = NULL_TREE;
/* No size arithmetic necessary, so the size check is
not needed. */
if (outer_nelts_check != NULL && inner_size.is_one ())
outer_nelts_check = NULL_TREE;
}
/* Perform the overflow check. */ /* Perform the overflow check. */
if (outer_nelts_check != NULL_TREE) if (outer_nelts_check != NULL_TREE)
size = fold_build3 (COND_EXPR, sizetype, outer_nelts_check, size = fold_build3 (COND_EXPR, sizetype, outer_nelts_check,
...@@ -2487,7 +2493,13 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts, ...@@ -2487,7 +2493,13 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts,
/* Use a global operator new. */ /* Use a global operator new. */
/* See if a cookie might be required. */ /* See if a cookie might be required. */
if (!(array_p && TYPE_VEC_NEW_USES_COOKIE (elt_type))) if (!(array_p && TYPE_VEC_NEW_USES_COOKIE (elt_type)))
cookie_size = NULL_TREE; {
cookie_size = NULL_TREE;
/* No size arithmetic necessary, so the size check is
not needed. */
if (outer_nelts_check != NULL && inner_size.is_one ())
outer_nelts_check = NULL_TREE;
}
alloc_call = build_operator_new_call (fnname, placement, alloc_call = build_operator_new_call (fnname, placement,
&size, &cookie_size, &size, &cookie_size,
......
2012-11-07 Florian Weimer <fweimer@redhat.com>
* g++.dg/init/new40.C: New.
2012-11-07 Jakub Jelinek <jakub@redhat.com> 2012-11-07 Jakub Jelinek <jakub@redhat.com>
PR debug/54693 PR debug/54693
......
// Testcase for overflow handling in operator new[].
// Optimization of unnecessary overflow checks.
// { dg-do run }
#include <assert.h>
#include <stdlib.h>
#include <stdexcept>
static size_t magic_allocation_size
= 1 + (size_t (1) << (sizeof (size_t) * 8 - 1));
struct exc : std::bad_alloc {
};
static size_t expected_size;
struct pod_with_new {
char ch;
void *operator new[] (size_t sz)
{
if (sz != expected_size)
abort ();
throw exc ();
}
};
struct with_new {
char ch;
with_new () { }
~with_new () { }
void *operator new[] (size_t sz)
{
if (sz != size_t (-1))
abort ();
throw exc ();
}
};
struct non_pod {
char ch;
non_pod () { }
~non_pod () { }
};
void *
operator new (size_t sz) _GLIBCXX_THROW (std::bad_alloc)
{
if (sz != expected_size)
abort ();
throw exc ();
}
int
main ()
{
if (sizeof (pod_with_new) == 1)
expected_size = magic_allocation_size;
else
expected_size = -1;
try {
new pod_with_new[magic_allocation_size];
abort ();
} catch (exc &) {
}
if (sizeof (with_new) == 1)
expected_size = magic_allocation_size;
else
expected_size = -1;
try {
new with_new[magic_allocation_size];
abort ();
} catch (exc &) {
}
expected_size = magic_allocation_size;
try {
new char[magic_allocation_size];
abort ();
} catch (exc &) {
}
expected_size = -1;
try {
new pod_with_new[magic_allocation_size][2];
abort ();
} catch (exc &) {
}
try {
new with_new[magic_allocation_size][2];
abort ();
} catch (exc &) {
}
try {
new char[magic_allocation_size][2];
abort ();
} catch (exc &) {
}
try {
new non_pod[magic_allocation_size];
abort ();
} catch (exc &) {
}
return 0;
}
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