From: Martin Sebor Date: Tue, 5 Nov 2019 16:20:44 +0000 (+0000) Subject: PR middle-end/92341 - missing -Warray-bounds indexing past the end of a compound... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=361d4a9eb6b397f3401b7693ee9fbc032e95a0f0;p=gcc.git PR middle-end/92341 - missing -Warray-bounds indexing past the end of a compound literal PR middle-end/92341 - missing -Warray-bounds indexing past the end of a compound literal PR middle-end/82612 - missing -Warray-bounds on a non-zero offset from the address of a non-array object gcc/testsuite/ChangeLog: PR middle-end/92341 PR middle-end/82612 * g++.dg/warn/Warray-bounds-4.C: Adjust text of expected warning. * gcc.dg/Warray-bounds-53.c: New test. * gcc.dg/Warray-bounds-54.c: New test. gcc/ChangeLog: PR middle-end/92341 PR middle-end/82612 * tree-sra.c (get_access_for_expr): Fail for out-of-bounds offsets. * tree-vrp.c (vrp_prop::check_array_ref): Correct index and text of message printed in a warning for empty arrays. (vrp_prop::check_mem_ref): Also handle function parameters and empty arrays. From-SVN: r277851 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 21304fdd30c..18247e7e87e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2019-11-04 Martin Sebor + + PR middle-end/92341 + PR middle-end/82612 + * tree-sra.c (get_access_for_expr): Fail for out-of-bounds offsets. + * tree-vrp.c (vrp_prop::check_array_ref): Correct index and text + of message printed in a warning for empty arrays. + (vrp_prop::check_mem_ref): Also handle function parameters and + empty arrays. + 2019-11-05 Richard Biener PR tree-optimization/92371 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 725cfa52f14..248d1807746 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2019-11-04 Martin Sebor + + PR middle-end/92341 + PR middle-end/82612 + * g++.dg/warn/Warray-bounds-4.C: Adjust text of expected warning. + * gcc.dg/Warray-bounds-53.c: New test. + * gcc.dg/Warray-bounds-54.c: New test. + 2019-11-05 Richard Biener PR tree-optimization/92371 diff --git a/gcc/testsuite/g++.dg/warn/Warray-bounds-4.C b/gcc/testsuite/g++.dg/warn/Warray-bounds-4.C index a4c43835aec..874aeee41e1 100644 --- a/gcc/testsuite/g++.dg/warn/Warray-bounds-4.C +++ b/gcc/testsuite/g++.dg/warn/Warray-bounds-4.C @@ -23,7 +23,7 @@ public: virtual void set(unsigned long index, char value) { contents[index] = value; } virtual char& operator[] (unsigned long index) { return contents[index]; } - FixedString() { contents[0] = '\0'; } // { dg-warning "above array bounds" } + FixedString() { contents[0] = '\0'; } // { dg-warning "\\\[-Warray-bounds" } }; void print_length (const String& string); diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-53.c b/gcc/testsuite/gcc.dg/Warray-bounds-53.c new file mode 100644 index 00000000000..0f062225b29 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-53.c @@ -0,0 +1,97 @@ +/* PR middle-end/92341 - missing -Warray-bounds indexing past the end + of a compound literal + { dg-do compile } + { dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */ + +#include "range.h" + +#define INT_MAX __INT_MAX__ +#define INT_MIN (-__INT_MAX__ - 1) + +void sink (int, ...); + + +#define T(...) sink (__LINE__, (__VA_ARGS__)) + + +void direct_idx_cst (void) +{ + T ((int[]){ }[-1]); // { dg-warning "array subscript -1 is outside array bounds of 'int\\\[0]'" } + T ((int[]){ }[0]); // { dg-warning "array subscript 0 is outside array bounds of 'int\\\[0]'" } + T ((int[]){ }[1]); // { dg-warning "array subscript 1 is outside array bounds of 'int\\\[0]'" } + + T ((int[]){ 1 }[-1]); // { dg-warning "array subscript -1 is below array bounds of 'int\\\[1]'" } + T ((int[]){ 1 }[0]); + T ((int[]){ 1 }[1]); // { dg-warning "array subscript 1 is above array bounds of 'int\\\[1]'" } + T ((int[]){ 1 }[INT_MIN]); // { dg-warning "array subscript -\[0-9\]+ is below array bounds of 'int\\\[1]'" } + T ((int[]){ 1 }[INT_MAX]); // { dg-warning "array subscript \[0-9\]+ is above array bounds of 'int\\\[1]'" } + T ((int[]){ 1 }[SIZE_MAX]); // { dg-warning "array subscript \[0-9\]+ is above array bounds of 'int\\\[1]'" } +} + + +void direct_idx_var (int i) +{ + T ((char[]){ }[i]); // { dg-warning "array subscript i is outside array bounds of 'char\\\[0]'" } + T ((int[]){ }[i]); // { dg-warning "array subscript i is outside array bounds of 'int\\\[0]'" } +} + + +void direct_idx_range (void) +{ + ptrdiff_t i = SR (-2, -1); + + T ((int[]){ 1 }[i]); // { dg-warning "array subscript \[ \n\r]+ is outside array bounds of 'int\\\[0]'" "pr?????" { xfail *-*-* } } +} + + +#undef T +#define T(idx, ...) do { \ + int *p = (__VA_ARGS__); \ + sink (p[idx]); \ + } while (0) + +void ptr_idx_cst (void) +{ + T (-1, (int[]){ }); // { dg-warning "array subscript -1 is outside array bounds of 'int\\\[0]'" } + T ( 0, (int[]){ }); // { dg-warning "array subscript 0 is outside array bounds of 'int\\\[0]'" } + T (+1, (int[]){ }); // { dg-warning "array subscript 1 is outside array bounds of 'int\\\[0]'" } + + T (-1, (int[]){ 1 }); // { dg-warning "array subscript -1 is outside array bounds of 'int\\\[1]'" } + T ( 0, (int[]){ 1 }); + T (+1, (int[]){ 1 }); // { dg-warning "array subscript 1 is outside array bounds of 'int\\\[1]'" } + T (INT_MIN, (int[]){ 1 }); // { dg-warning "array subscript -\[0-9\]+ is outside array bounds of 'int\\\[1]'" "pr92381" { xfail ilp32 } } + T (INT_MAX, (int[]){ 1 }); // { dg-warning "array subscript \[0-9\]+ is outside array bounds of 'int\\\[1]'" "pr92381" { xfail ilp32 } } + // { dg-warning "array subscript -\[0-9\]+ is outside array bounds of 'int\\\[1]'" "" { target ilp32 } .-1 } + T (SIZE_MAX, (int[]){ 1 }); // { dg-warning "array subscript -?\[0-9\]+ is outside array bounds of 'int\\\[1]'" } +} + + +void ptr_idx_var (int i) +{ + T (i, (int[]){ }); // { dg-warning "array subscript \[^\n\r\]+ is outside array bounds of 'int\\\[0]'" } + T (i, (int[]){ 1 }); + T (i, (int[]){ i, 1 }); +} + +void ptr_idx_range (void) +{ + ptrdiff_t i = SR (-2, -1); + + T (i, (int[]){ }); // { dg-warning "array subscript \\\[-2, -1] is outside array bounds of 'int\\\[0]'" } + T (i, (int[]){ 1 }); // { dg-warning "array subscript \\\[-2, -1] is outside array bounds of 'int\\\[1]'" } + T (i, (int[]){ i }); // { dg-warning "array subscript \\\[-2, -1] is outside array bounds of 'int\\\[1]'" } + + i = SR (0, 1); + + T (i, (int[]){ }); // { dg-warning "array subscript \\\[0, 1] is outside array bounds of 'int\\\[0]'" } + T (i, (int[]){ 1 }); + + i = SR (1, 2); + T (i, (int[]){ 1 }); // { dg-warning "array subscript \\\[1, 2] is outside array bounds of 'int\\\[1]'" } + + i = SR (2, 3); + T (i, (int[]){ 1, 2, 3 }); + + i = SR (3, 4); + T (i, (int[]){ 2, 3, 4 }); // { dg-warning "array subscript \\\[3, 4] is outside array bounds of 'int\\\[3]'" } +} diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-54.c b/gcc/testsuite/gcc.dg/Warray-bounds-54.c new file mode 100644 index 00000000000..644fcd02cb6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-54.c @@ -0,0 +1,24 @@ +/* PR middle-end/82612 - missing -Warray-bounds on a non-zero offset + from the address of a non-array object + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +int i; +int f0 (void) +{ + int *p = &i; + return p[2]; // { dg-warning "-Warray-bounds" } +} + +int f1 (void) +{ + int i; + int *p = &i; + return p[2]; // { dg-warning "-Warray-bounds" } +} + +int f2 (int i) +{ + int *p = &i; + return p[2]; // { dg-warning "-Warray-bounds" } +} diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 3f104238d93..44862690559 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -3068,6 +3068,13 @@ get_access_for_expr (tree expr) || !DECL_P (base)) return NULL; + if (tree basesize = DECL_SIZE (base)) + { + poly_int64 sz = tree_to_poly_int64 (basesize); + if (offset < 0 || known_le (sz, offset)) + return NULL; + } + if (!bitmap_bit_p (candidate_bitmap, DECL_UID (base))) return NULL; diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 1328707a154..940ed9cb7dc 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -4083,18 +4083,18 @@ bool vrp_prop::check_array_ref (location_t location, tree ref, bool ignore_off_by_one) { - tree low_sub, up_sub; - tree low_bound, up_bound, up_bound_p1; - if (TREE_NO_WARNING (ref)) return false; - low_sub = up_sub = TREE_OPERAND (ref, 1); - up_bound = array_ref_up_bound (ref); + tree low_sub = TREE_OPERAND (ref, 1); + tree up_sub = low_sub; + tree up_bound = array_ref_up_bound (ref); /* Set for accesses to interior zero-length arrays. */ bool interior_zero_len = false; + tree up_bound_p1; + if (!up_bound || TREE_CODE (up_bound) != INTEGER_CST || (warn_array_bounds < 2 @@ -4148,7 +4148,7 @@ vrp_prop::check_array_ref (location_t location, tree ref, up_bound_p1 = int_const_binop (PLUS_EXPR, up_bound, build_int_cst (TREE_TYPE (up_bound), 1)); - low_bound = array_ref_low_bound (ref); + tree low_bound = array_ref_low_bound (ref); tree artype = TREE_TYPE (TREE_OPERAND (ref, 0)); @@ -4157,8 +4157,8 @@ vrp_prop::check_array_ref (location_t location, tree ref, /* Empty array. */ if (up_bound && tree_int_cst_equal (low_bound, up_bound_p1)) warned = warning_at (location, OPT_Warray_bounds, - "array subscript %E is above array bounds of %qT", - low_bound, artype); + "array subscript %E is outside array bounds of %qT", + low_sub, artype); const value_range_equiv *vr = NULL; if (TREE_CODE (low_sub) == SSA_NAME) @@ -4372,6 +4372,7 @@ vrp_prop::check_mem_ref (location_t location, tree ref, { arg = TREE_OPERAND (arg, 0); if (TREE_CODE (arg) != STRING_CST + && TREE_CODE (arg) != PARM_DECL && TREE_CODE (arg) != VAR_DECL) return false; } @@ -4455,7 +4456,9 @@ vrp_prop::check_mem_ref (location_t location, tree ref, if (ignore_off_by_one) ubound += 1; - if (offrange[0] >= ubound || offrange[1] < arrbounds[0]) + if (arrbounds[0] == arrbounds[1] + || offrange[0] >= ubound + || offrange[1] < arrbounds[0]) { /* Treat a reference to a non-array object as one to an array of a single element. */