aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vrp.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2017-11-22 13:35:26 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2017-11-22 13:35:26 +0100
commitff4790688bffc52c1a76aaf35c01fe92009a99ff (patch)
treea521783bec9aa30d6cddf1a23ea52f02f1239b4c /gcc/tree-vrp.c
parenta7d3cd407ccea644f1405cf331edf3bb30e57e65 (diff)
downloadgcc-ff4790688bffc52c1a76aaf35c01fe92009a99ff.zip
gcc-ff4790688bffc52c1a76aaf35c01fe92009a99ff.tar.gz
gcc-ff4790688bffc52c1a76aaf35c01fe92009a99ff.tar.bz2
re PR tree-optimization/83044 (ice in contains_struct_check)
PR tree-optimization/83044 * tree-vrp.c (vrp_prop::check_array_ref): If eltsize is not INTEGER_CST or is 0, clear up_bound{,_p1} and later ignore tests that need the upper bound. Subtract offset from get_addr_base_and_unit_offset only if positive and subtract it before division by eltsize rather than after it. * gcc.dg/pr83044.c: New test. * c-c++-common/Warray-bounds.c (fb): Fix up MAX value. From-SVN: r255054
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r--gcc/tree-vrp.c46
1 files changed, 27 insertions, 19 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index e248f59..ea56e9d 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -4795,24 +4795,30 @@ vrp_prop::check_array_ref (location_t location, tree ref,
the size of the largest object is PTRDIFF_MAX. */
tree eltsize = array_ref_element_size (ref);
- /* FIXME: Handle VLAs. */
- if (TREE_CODE (eltsize) != INTEGER_CST)
- return;
-
- tree maxbound = TYPE_MAX_VALUE (ptrdiff_type_node);
-
- up_bound_p1 = int_const_binop (TRUNC_DIV_EXPR, maxbound, eltsize);
-
- tree arg = TREE_OPERAND (ref, 0);
+ if (TREE_CODE (eltsize) != INTEGER_CST
+ || integer_zerop (eltsize))
+ {
+ up_bound = NULL_TREE;
+ up_bound_p1 = NULL_TREE;
+ }
+ else
+ {
+ tree maxbound = TYPE_MAX_VALUE (ptrdiff_type_node);
+ tree arg = TREE_OPERAND (ref, 0);
+ HOST_WIDE_INT off;
+
+ if (get_addr_base_and_unit_offset (arg, &off) && off > 0)
+ maxbound = wide_int_to_tree (sizetype,
+ wi::sub (wi::to_wide (maxbound),
+ off));
+ else
+ maxbound = fold_convert (sizetype, maxbound);
- HOST_WIDE_INT off;
- if (get_addr_base_and_unit_offset (arg, &off))
- up_bound_p1 = wide_int_to_tree (sizetype,
- wi::sub (wi::to_wide (up_bound_p1),
- off));
+ up_bound_p1 = int_const_binop (TRUNC_DIV_EXPR, maxbound, eltsize);
- up_bound = int_const_binop (MINUS_EXPR, up_bound_p1,
- build_int_cst (ptrdiff_type_node, 1));
+ up_bound = int_const_binop (MINUS_EXPR, up_bound_p1,
+ build_int_cst (ptrdiff_type_node, 1));
+ }
}
else
up_bound_p1 = int_const_binop (PLUS_EXPR, up_bound,
@@ -4823,7 +4829,7 @@ vrp_prop::check_array_ref (location_t location, tree ref,
tree artype = TREE_TYPE (TREE_OPERAND (ref, 0));
/* Empty array. */
- if (tree_int_cst_equal (low_bound, up_bound_p1))
+ if (up_bound && tree_int_cst_equal (low_bound, up_bound_p1))
{
warning_at (location, OPT_Warray_bounds,
"array subscript %E is above array bounds of %qT",
@@ -4843,7 +4849,8 @@ vrp_prop::check_array_ref (location_t location, tree ref,
if (vr && vr->type == VR_ANTI_RANGE)
{
- if (TREE_CODE (up_sub) == INTEGER_CST
+ if (up_bound
+ && TREE_CODE (up_sub) == INTEGER_CST
&& (ignore_off_by_one
? tree_int_cst_lt (up_bound, up_sub)
: tree_int_cst_le (up_bound, up_sub))
@@ -4856,7 +4863,8 @@ vrp_prop::check_array_ref (location_t location, tree ref,
TREE_NO_WARNING (ref) = 1;
}
}
- else if (TREE_CODE (up_sub) == INTEGER_CST
+ else if (up_bound
+ && TREE_CODE (up_sub) == INTEGER_CST
&& (ignore_off_by_one
? !tree_int_cst_le (up_sub, up_bound_p1)
: !tree_int_cst_le (up_sub, up_bound)))