Commit 83ede847 by Richard Biener Committed by Richard Biener

re PR tree-optimization/55079 (false positive -Warray-bounds (also seen at -O3 bootstrap))

2012-12-11  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/55079
	* tree-vrp.c (extract_range_from_binary_expr_1): Handle MAX/MIN_EXPR
	for more cases.
	(register_edge_assert_for_2): Register asserts for post-in/decrement
	tests.
	(check_array_ref): Dump what expression we emit array bound
	warnings for.
	(search_for_addr_array): Likewise.

	* gcc.dg/Warray-bounds-9.c: New testcase.
	* gcc.dg/Warray-bounds-10.c: Likewise.
	* gcc.dg/tree-ssa/ssa-pre-1.c: Adjust.

From-SVN: r194388
parent c401fb6f
2012-12-11 Richard Biener <rguenther@suse.de>
PR tree-optimization/55079
* tree-vrp.c (extract_range_from_binary_expr_1): Handle MAX/MIN_EXPR
for more cases.
(register_edge_assert_for_2): Register asserts for post-in/decrement
tests.
(check_array_ref): Dump what expression we emit array bound
warnings for.
(search_for_addr_array): Likewise.
2012-12-11 Eric Botcazou <ebotcazou@adacore.com>
* tree-ssa-loop-ivopts.c (prepare_decl_rtl) <ADDR_EXPR>: Generate RTL
2012-12-11 Richard Biener <rguenther@suse.de>
PR tree-optimization/55079
* gcc.dg/Warray-bounds-9.c: New testcase.
* gcc.dg/Warray-bounds-10.c: Likewise.
* gcc.dg/tree-ssa/ssa-pre-1.c: Adjust.
2012-12-10 Janus Weil <janus@gcc.gnu.org>
PR fortran/52909
......
/* { dg-do compile } */
/* { dg-options "-O3 -Warray-bounds" } */
int f(unsigned len, int buflen)
{
unsigned taillen;
unsigned slen;
unsigned i;
int b[17]; /* needed <= 17 to trigger Warning */
int j = 0; /* needed to trigger Warning */
b[0] = 0;
taillen= buflen & 7; /* taillen [0..7] */
if(taillen) { /* taillen [1..7] */
slen= 8 - taillen; /* slen [7..1] */
if (len<slen) /* needed to trigger Warning */
slen=len; /* slen' < slen */
for(i=0; i<slen; i++) {
j = b[taillen]; /* taillen + slen = [1..7] + [7..1] = 8 */
taillen++;
}
}
return j;
}
/* { dg-do compile } */
/* { dg-options "-O3 -Warray-bounds" } */
int a[8];
void
test(unsigned int n)
{
unsigned int i;
unsigned int j;
if (n<8)
for (j=0;j<n;j++)
{
i = j;
do
a[i+1]=a[i];
while (i--);
}
}
......@@ -2349,6 +2349,8 @@ extract_range_from_binary_expr_1 (value_range_t *vr,
&& code != EXACT_DIV_EXPR
&& code != ROUND_DIV_EXPR
&& code != TRUNC_MOD_EXPR
&& code != MIN_EXPR
&& code != MAX_EXPR
&& (vr0.type == VR_VARYING
|| vr1.type == VR_VARYING
|| vr0.type != vr1.type
......@@ -2602,21 +2604,49 @@ extract_range_from_binary_expr_1 (value_range_t *vr,
else if (code == MIN_EXPR
|| code == MAX_EXPR)
{
if (vr0.type == VR_ANTI_RANGE)
if (vr0.type == VR_RANGE
&& !symbolic_range_p (&vr0))
{
type = VR_RANGE;
if (vr1.type == VR_RANGE
&& !symbolic_range_p (&vr1))
{
/* For operations that make the resulting range directly
proportional to the original ranges, apply the operation to
the same end of each range. */
min = vrp_int_const_binop (code, vr0.min, vr1.min);
max = vrp_int_const_binop (code, vr0.max, vr1.max);
}
else if (code == MIN_EXPR)
{
min = vrp_val_min (expr_type);
max = vr0.max;
}
else if (code == MAX_EXPR)
{
min = vr0.min;
max = vrp_val_max (expr_type);
}
}
else if (vr1.type == VR_RANGE
&& !symbolic_range_p (&vr1))
{
/* For MIN_EXPR and MAX_EXPR with two VR_ANTI_RANGEs,
the resulting VR_ANTI_RANGE is the same - intersection
of the two ranges. */
min = vrp_int_const_binop (MAX_EXPR, vr0.min, vr1.min);
max = vrp_int_const_binop (MIN_EXPR, vr0.max, vr1.max);
type = VR_RANGE;
if (code == MIN_EXPR)
{
min = vrp_val_min (expr_type);
max = vr1.max;
}
else if (code == MAX_EXPR)
{
min = vr1.min;
max = vrp_val_max (expr_type);
}
}
else
{
/* For operations that make the resulting range directly
proportional to the original ranges, apply the operation to
the same end of each range. */
min = vrp_int_const_binop (code, vr0.min, vr1.min);
max = vrp_int_const_binop (code, vr0.max, vr1.max);
set_value_range_to_varying (vr);
return;
}
}
else if (code == MULT_EXPR)
......@@ -4707,6 +4737,45 @@ register_edge_assert_for_2 (tree name, edge e, gimple_stmt_iterator bsi,
}
}
/* In the case of post-in/decrement tests like if (i++) ... and uses
of the in/decremented value on the edge the extra name we want to
assert for is not on the def chain of the name compared. Instead
it is in the set of use stmts. */
if ((comp_code == NE_EXPR
|| comp_code == EQ_EXPR)
&& TREE_CODE (val) == INTEGER_CST)
{
imm_use_iterator ui;
gimple use_stmt;
FOR_EACH_IMM_USE_STMT (use_stmt, ui, name)
{
/* Cut off to use-stmts that are in the predecessor. */
if (gimple_bb (use_stmt) != e->src)
continue;
if (!is_gimple_assign (use_stmt))
continue;
enum tree_code code = gimple_assign_rhs_code (use_stmt);
if (code != PLUS_EXPR
&& code != MINUS_EXPR)
continue;
tree cst = gimple_assign_rhs2 (use_stmt);
if (TREE_CODE (cst) != INTEGER_CST)
continue;
tree name2 = gimple_assign_lhs (use_stmt);
if (live_on_edge (e, name2))
{
cst = int_const_binop (code, val, cst);
register_new_assert_for (name2, name2, comp_code, cst,
NULL, e, bsi);
retval = true;
}
}
}
if (TREE_CODE_CLASS (comp_code) == tcc_comparison
&& TREE_CODE (val) == INTEGER_CST)
{
......@@ -5943,6 +6012,11 @@ check_array_ref (location_t location, tree ref, bool ignore_off_by_one)
: (tree_int_cst_lt (up_bound, up_sub)
|| tree_int_cst_equal (up_bound_p1, up_sub))))
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Array bound warning for ");
dump_generic_expr (MSG_NOTE, TDF_SLIM, ref);
}
warning_at (location, OPT_Warray_bounds,
"array subscript is above array bounds");
TREE_NO_WARNING (ref) = 1;
......@@ -5950,6 +6024,11 @@ check_array_ref (location_t location, tree ref, bool ignore_off_by_one)
else if (TREE_CODE (low_sub) == INTEGER_CST
&& tree_int_cst_lt (low_sub, low_bound))
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Array bound warning for ");
dump_generic_expr (MSG_NOTE, TDF_SLIM, ref);
}
warning_at (location, OPT_Warray_bounds,
"array subscript is below array bounds");
TREE_NO_WARNING (ref) = 1;
......@@ -6018,6 +6097,11 @@ search_for_addr_array (tree t, location_t location)
idx = idx.sdiv (tree_to_double_int (el_sz), TRUNC_DIV_EXPR);
if (idx.slt (double_int_zero))
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Array bound warning for ");
dump_generic_expr (MSG_NOTE, TDF_SLIM, t);
}
warning_at (location, OPT_Warray_bounds,
"array subscript is below array bounds");
TREE_NO_WARNING (t) = 1;
......@@ -6026,6 +6110,11 @@ search_for_addr_array (tree t, location_t location)
- tree_to_double_int (low_bound)
+ double_int_one))
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Array bound warning for ");
dump_generic_expr (MSG_NOTE, TDF_SLIM, t);
}
warning_at (location, OPT_Warray_bounds,
"array subscript is above array bounds");
TREE_NO_WARNING (t) = 1;
......
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