diff options
author | Jakub Jelinek <jakub@redhat.com> | 2017-11-22 13:35:26 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2017-11-22 13:35:26 +0100 |
commit | ff4790688bffc52c1a76aaf35c01fe92009a99ff (patch) | |
tree | a521783bec9aa30d6cddf1a23ea52f02f1239b4c /gcc | |
parent | a7d3cd407ccea644f1405cf331edf3bb30e57e65 (diff) | |
download | gcc-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')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/Warray-bounds.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr83044.c | 14 | ||||
-rw-r--r-- | gcc/tree-vrp.c | 46 |
5 files changed, 55 insertions, 20 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index edd3621..e4936c6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,12 @@ 2017-11-22 Jakub Jelinek <jakub@redhat.com> + 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. + PR debug/83084 * valtrack.c (propagate_for_debug_subst, propagate_for_debug): Reset debug insns if they would contain UNSPEC_VOLATILE or volatile asm. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 39dd144..b117fa8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2017-11-22 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/83044 + * gcc.dg/pr83044.c: New test. + * c-c++-common/Warray-bounds.c (fb): Fix up MAX value. + 2017-11-22 Paul Thomas <pault@gcc.gnu.org> PR fortran/79072 diff --git a/gcc/testsuite/c-c++-common/Warray-bounds.c b/gcc/testsuite/c-c++-common/Warray-bounds.c index bea36fb..4b9d6aa 100644 --- a/gcc/testsuite/c-c++-common/Warray-bounds.c +++ b/gcc/testsuite/c-c++-common/Warray-bounds.c @@ -200,7 +200,7 @@ void fb (struct B *p) T (p->a1x[9].a1[0]); - enum { MAX = DIFF_MAX / sizeof *p->a1x - sizeof *p }; + enum { MAX = (DIFF_MAX - sizeof *p) / sizeof *p->a1x }; T (p->a1x[DIFF_MIN].a1); /* { dg-warning "array subscript -\[0-9\]+ is below array bounds" } */ T (p->a1x[-1].a1); /* { dg-warning "array subscript -1 is below array bounds" } */ diff --git a/gcc/testsuite/gcc.dg/pr83044.c b/gcc/testsuite/gcc.dg/pr83044.c new file mode 100644 index 0000000..6681071 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr83044.c @@ -0,0 +1,14 @@ +/* PR tree-optimization/83044 */ +/* { dg-do compile } */ +/* { dg-options "-Wall -std=gnu89 -O2" } */ + +struct A { int b[0]; }; +struct B { struct A c[0]; }; +void bar (int *); + +void +foo (void) +{ + struct B d; + bar (d.c->b); +} 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))) |