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
This commit is contained in:
parent
c401fb6f18
commit
83ede847e8
@ -1,3 +1,14 @@
|
|||||||
|
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>
|
2012-12-11 Eric Botcazou <ebotcazou@adacore.com>
|
||||||
|
|
||||||
* tree-ssa-loop-ivopts.c (prepare_decl_rtl) <ADDR_EXPR>: Generate RTL
|
* tree-ssa-loop-ivopts.c (prepare_decl_rtl) <ADDR_EXPR>: Generate RTL
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
|
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>
|
2012-12-10 Janus Weil <janus@gcc.gnu.org>
|
||||||
|
|
||||||
PR fortran/52909
|
PR fortran/52909
|
||||||
|
25
gcc/testsuite/gcc.dg/Warray-bounds-10.c
Normal file
25
gcc/testsuite/gcc.dg/Warray-bounds-10.c
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/* { 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;
|
||||||
|
}
|
19
gcc/testsuite/gcc.dg/Warray-bounds-9.c
Normal file
19
gcc/testsuite/gcc.dg/Warray-bounds-9.c
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/* { 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--);
|
||||||
|
}
|
||||||
|
}
|
111
gcc/tree-vrp.c
111
gcc/tree-vrp.c
@ -2349,6 +2349,8 @@ extract_range_from_binary_expr_1 (value_range_t *vr,
|
|||||||
&& code != EXACT_DIV_EXPR
|
&& code != EXACT_DIV_EXPR
|
||||||
&& code != ROUND_DIV_EXPR
|
&& code != ROUND_DIV_EXPR
|
||||||
&& code != TRUNC_MOD_EXPR
|
&& code != TRUNC_MOD_EXPR
|
||||||
|
&& code != MIN_EXPR
|
||||||
|
&& code != MAX_EXPR
|
||||||
&& (vr0.type == VR_VARYING
|
&& (vr0.type == VR_VARYING
|
||||||
|| vr1.type == VR_VARYING
|
|| vr1.type == VR_VARYING
|
||||||
|| vr0.type != vr1.type
|
|| vr0.type != vr1.type
|
||||||
@ -2602,21 +2604,49 @@ extract_range_from_binary_expr_1 (value_range_t *vr,
|
|||||||
else if (code == MIN_EXPR
|
else if (code == MIN_EXPR
|
||||||
|| code == MAX_EXPR)
|
|| code == MAX_EXPR)
|
||||||
{
|
{
|
||||||
if (vr0.type == VR_ANTI_RANGE)
|
if (vr0.type == VR_RANGE
|
||||||
|
&& !symbolic_range_p (&vr0))
|
||||||
{
|
{
|
||||||
/* For MIN_EXPR and MAX_EXPR with two VR_ANTI_RANGEs,
|
type = VR_RANGE;
|
||||||
the resulting VR_ANTI_RANGE is the same - intersection
|
if (vr1.type == VR_RANGE
|
||||||
of the two ranges. */
|
&& !symbolic_range_p (&vr1))
|
||||||
min = vrp_int_const_binop (MAX_EXPR, vr0.min, vr1.min);
|
{
|
||||||
max = vrp_int_const_binop (MIN_EXPR, vr0.max, vr1.max);
|
/* 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))
|
||||||
|
{
|
||||||
|
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
|
else
|
||||||
{
|
{
|
||||||
/* For operations that make the resulting range directly
|
set_value_range_to_varying (vr);
|
||||||
proportional to the original ranges, apply the operation to
|
return;
|
||||||
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 == MULT_EXPR)
|
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
|
if (TREE_CODE_CLASS (comp_code) == tcc_comparison
|
||||||
&& TREE_CODE (val) == INTEGER_CST)
|
&& 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_lt (up_bound, up_sub)
|
||||||
|| tree_int_cst_equal (up_bound_p1, 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,
|
warning_at (location, OPT_Warray_bounds,
|
||||||
"array subscript is above array bounds");
|
"array subscript is above array bounds");
|
||||||
TREE_NO_WARNING (ref) = 1;
|
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
|
else if (TREE_CODE (low_sub) == INTEGER_CST
|
||||||
&& tree_int_cst_lt (low_sub, low_bound))
|
&& 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,
|
warning_at (location, OPT_Warray_bounds,
|
||||||
"array subscript is below array bounds");
|
"array subscript is below array bounds");
|
||||||
TREE_NO_WARNING (ref) = 1;
|
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);
|
idx = idx.sdiv (tree_to_double_int (el_sz), TRUNC_DIV_EXPR);
|
||||||
if (idx.slt (double_int_zero))
|
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,
|
warning_at (location, OPT_Warray_bounds,
|
||||||
"array subscript is below array bounds");
|
"array subscript is below array bounds");
|
||||||
TREE_NO_WARNING (t) = 1;
|
TREE_NO_WARNING (t) = 1;
|
||||||
@ -6026,6 +6110,11 @@ search_for_addr_array (tree t, location_t location)
|
|||||||
- tree_to_double_int (low_bound)
|
- tree_to_double_int (low_bound)
|
||||||
+ double_int_one))
|
+ 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,
|
warning_at (location, OPT_Warray_bounds,
|
||||||
"array subscript is above array bounds");
|
"array subscript is above array bounds");
|
||||||
TREE_NO_WARNING (t) = 1;
|
TREE_NO_WARNING (t) = 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user