Commit f8269ad4 by Richard Biener Committed by Richard Biener

re PR tree-optimization/64277 (Incorrect warning "array subscript is above array bounds")

2015-04-16  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/64277
	* tree-vrp.c (check_array_ref): Fix anti-range handling,
	simplify upper bound handling.
	(search_for_addr_array): Simplify.
	(check_array_bounds): Handle ADDR_EXPRs here.
	(check_all_array_refs): Simplify.

	* gcc.dg/Warray-bounds-14.c: New testcase.
	* gcc.dg/Warray-bounds-15.c: Likewise.
	* c-c++-common/ubsan/bounds-4.c: Disable -Warray-bounds.
	* c-c++-common/ubsan/bounds-6.c: Likewise.

From-SVN: r222146
parent 579cef8f
2015-04-16 Richard Biener <rguenther@suse.de>
PR tree-optimization/64277
* tree-vrp.c (check_array_ref): Fix anti-range handling,
simplify upper bound handling.
(search_for_addr_array): Simplify.
(check_array_bounds): Handle ADDR_EXPRs here.
(check_all_array_refs): Simplify.
2015-04-16 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.c (print_reg): Rewrite function.
......
2015-04-16 Richard Biener <rguenther@suse.de>
PR tree-optimization/64277
* gcc.dg/Warray-bounds-14.c: New testcase.
* gcc.dg/Warray-bounds-15.c: Likewise.
* c-c++-common/ubsan/bounds-4.c: Disable -Warray-bounds.
* c-c++-common/ubsan/bounds-6.c: Likewise.
2015-04-16 Renlin Li <renlin.li@arm.com>
* gcc.target/aarch64/unsigned-unsignedfloat.c: New.
......
/* { dg-do compile } */
/* { dg-options "-fsanitize=bounds -Wall -Wextra -Wno-unused" } */
/* { dg-options "-fsanitize=bounds -Wall -Wextra -Wno-array-bounds -Wno-unused" } */
/* Initializers of TREE_STATICs aren't instrumented.
But don't ICE on 'em. */
......@@ -11,7 +11,7 @@ int *gpi;
int
main (void)
{
gpi = &A[4];
gpi = &A[4]; /* This will warn with -Warray-bounds, but only if VRP runs. */
static int *pi = &A[4];
return 0;
}
/* { dg-do run } */
/* { dg-options "-fsanitize=bounds -Wall -Wextra" } */
/* { dg-options "-fsanitize=bounds -Wall -Wextra -Wno-array-bounds" } */
/* Test off-by-one. */
......@@ -24,7 +24,7 @@ main (void)
a = &u[4].a[10]; // Error
a = &u[3].a[9]; // OK
a = &u[3].a[10]; // OK
a = &u[3].a[11]; // Error
a = &u[3].a[11]; // Error, warns with -Warray-bounds, but only if VRP runs
return 0;
}
......
/* { dg-do compile } */
/* { dg-options "-O2 -Warray-bounds" } */
int a[10];
int foo1 (int i)
{
if (i < 0 || i > 9)
return a[i]; /* { dg-warning "outside array bounds" } */
return 0;
}
int foo2 (int i)
{
if (i < 0 || i > 8)
return a[i]; /* { dg-bogus "outside array bounds" } */
return 0;
}
int *foo3 (int i)
{
if (i < 0 || i > 10)
return &a[i]; /* { dg-warning "outside array bounds" } */
return (void *)0;
}
int *foo4 (int i)
{
if (i < 0 || i > 9)
return &a[i]; /* { dg-bogus "outside array bounds" } */
return (void *)0;
}
/* { dg-do compile } */
/* { dg-options "-O2 -Warray-bounds" } */
int a[10];
int *foo1 (int i)
{
return &a[10]; /* { dg-bogus "above array bounds" } */
}
int *foo2 (int i)
{
return &a[11]; /* { dg-warning "above array bounds" } */
}
int foo3 (int i)
{
return a[9]; /* { dg-bogus "above array bounds" } */
}
int foo4 (int i)
{
return a[10]; /* { dg-warning "above array bounds" } */
}
......@@ -6565,6 +6565,14 @@ check_array_ref (location_t location, tree ref, bool ignore_off_by_one)
up_bound_p1 = int_const_binop (PLUS_EXPR, up_bound,
build_int_cst (TREE_TYPE (up_bound), 1));
/* Empty array. */
if (tree_int_cst_equal (low_bound, up_bound_p1))
{
warning_at (location, OPT_Warray_bounds,
"array subscript is above array bounds");
TREE_NO_WARNING (ref) = 1;
}
if (TREE_CODE (low_sub) == SSA_NAME)
{
vr = get_value_range (low_sub);
......@@ -6578,9 +6586,11 @@ check_array_ref (location_t location, tree ref, bool ignore_off_by_one)
if (vr && vr->type == VR_ANTI_RANGE)
{
if (TREE_CODE (up_sub) == INTEGER_CST
&& tree_int_cst_lt (up_bound, up_sub)
&& (ignore_off_by_one
? tree_int_cst_lt (up_bound, up_sub)
: tree_int_cst_le (up_bound, up_sub))
&& TREE_CODE (low_sub) == INTEGER_CST
&& tree_int_cst_lt (low_sub, low_bound))
&& tree_int_cst_le (low_sub, low_bound))
{
warning_at (location, OPT_Warray_bounds,
"array subscript is outside array bounds");
......@@ -6589,10 +6599,8 @@ check_array_ref (location_t location, tree ref, bool ignore_off_by_one)
}
else if (TREE_CODE (up_sub) == INTEGER_CST
&& (ignore_off_by_one
? (tree_int_cst_lt (up_bound, up_sub)
&& !tree_int_cst_equal (up_bound_p1, up_sub))
: (tree_int_cst_lt (up_bound, up_sub)
|| tree_int_cst_equal (up_bound_p1, up_sub))))
? !tree_int_cst_le (up_sub, up_bound_p1)
: !tree_int_cst_le (up_sub, up_bound)))
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
......@@ -6625,25 +6633,6 @@ check_array_ref (location_t location, tree ref, bool ignore_off_by_one)
static void
search_for_addr_array (tree t, location_t location)
{
while (TREE_CODE (t) == SSA_NAME)
{
gimple g = SSA_NAME_DEF_STMT (t);
if (gimple_code (g) != GIMPLE_ASSIGN)
return;
if (get_gimple_rhs_class (gimple_assign_rhs_code (g))
!= GIMPLE_SINGLE_RHS)
return;
t = gimple_assign_rhs1 (g);
}
/* We are only interested in addresses of ARRAY_REF's. */
if (TREE_CODE (t) != ADDR_EXPR)
return;
/* Check each ARRAY_REFs in the reference chain. */
do
{
......@@ -6733,12 +6722,11 @@ check_array_bounds (tree *tp, int *walk_subtree, void *data)
if (TREE_CODE (t) == ARRAY_REF)
check_array_ref (location, t, false /*ignore_off_by_one*/);
if (TREE_CODE (t) == MEM_REF
|| (TREE_CODE (t) == RETURN_EXPR && TREE_OPERAND (t, 0)))
search_for_addr_array (TREE_OPERAND (t, 0), location);
if (TREE_CODE (t) == ADDR_EXPR)
*walk_subtree = FALSE;
else if (TREE_CODE (t) == ADDR_EXPR)
{
search_for_addr_array (t, location);
*walk_subtree = FALSE;
}
return NULL_TREE;
}
......@@ -6768,29 +6756,17 @@ check_all_array_refs (void)
{
gimple stmt = gsi_stmt (si);
struct walk_stmt_info wi;
if (!gimple_has_location (stmt))
if (!gimple_has_location (stmt)
|| is_gimple_debug (stmt))
continue;
if (is_gimple_call (stmt))
{
size_t i;
size_t n = gimple_call_num_args (stmt);
for (i = 0; i < n; i++)
{
tree arg = gimple_call_arg (stmt, i);
search_for_addr_array (arg, gimple_location (stmt));
}
}
else
{
memset (&wi, 0, sizeof (wi));
wi.info = CONST_CAST (void *, (const void *)
gimple_location_ptr (stmt));
memset (&wi, 0, sizeof (wi));
wi.info = CONST_CAST (void *, (const void *)
gimple_location_ptr (stmt));
walk_gimple_op (gsi_stmt (si),
check_array_bounds,
&wi);
}
walk_gimple_op (gsi_stmt (si),
check_array_bounds,
&wi);
}
}
}
......
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