From: Richard Biener Date: Thu, 16 Apr 2015 12:03:11 +0000 (+0000) Subject: re PR tree-optimization/64277 (Incorrect warning "array subscript is above array... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f8269ad4a97c7a4c950fcf42de24d6f145037e7e;p=gcc.git re PR tree-optimization/64277 (Incorrect warning "array subscript is above array bounds") 2015-04-16 Richard Biener 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4b661d1c928..c4d0c150736 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2015-04-16 Richard Biener + + 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 * config/i386/i386.c (print_reg): Rewrite function. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f8e227965eb..5a217e7dc2c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2015-04-16 Richard Biener + + 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 * gcc.target/aarch64/unsigned-unsignedfloat.c: New. diff --git a/gcc/testsuite/c-c++-common/ubsan/bounds-4.c b/gcc/testsuite/c-c++-common/ubsan/bounds-4.c index 7748780884c..88e7e14050e 100644 --- a/gcc/testsuite/c-c++-common/ubsan/bounds-4.c +++ b/gcc/testsuite/c-c++-common/ubsan/bounds-4.c @@ -1,5 +1,5 @@ /* { 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; } diff --git a/gcc/testsuite/c-c++-common/ubsan/bounds-6.c b/gcc/testsuite/c-c++-common/ubsan/bounds-6.c index aef2055fb3c..952354985d7 100644 --- a/gcc/testsuite/c-c++-common/ubsan/bounds-6.c +++ b/gcc/testsuite/c-c++-common/ubsan/bounds-6.c @@ -1,5 +1,5 @@ /* { 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; } diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-14.c b/gcc/testsuite/gcc.dg/Warray-bounds-14.c new file mode 100644 index 00000000000..f3a33f9c7db --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-14.c @@ -0,0 +1,28 @@ +/* { 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; +} diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-15.c b/gcc/testsuite/gcc.dg/Warray-bounds-15.c new file mode 100644 index 00000000000..f50e5ee7cf3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-15.c @@ -0,0 +1,20 @@ +/* { 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" } */ +} diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 23e48b1144d..41d7316865a 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -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); } } }