aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2019-11-05 16:20:44 +0000
committerMartin Sebor <msebor@gcc.gnu.org>2019-11-05 09:20:44 -0700
commit361d4a9eb6b397f3401b7693ee9fbc032e95a0f0 (patch)
treed0efeac99cf67e900fd19921105e9211998dbe51
parent02bf7e6fa219f939b3225c54fbe8bab2133b1aeb (diff)
downloadgcc-361d4a9eb6b397f3401b7693ee9fbc032e95a0f0.zip
gcc-361d4a9eb6b397f3401b7693ee9fbc032e95a0f0.tar.gz
gcc-361d4a9eb6b397f3401b7693ee9fbc032e95a0f0.tar.bz2
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
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/g++.dg/warn/Warray-bounds-4.C2
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-53.c97
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-54.c24
-rw-r--r--gcc/tree-sra.c7
-rw-r--r--gcc/tree-vrp.c21
7 files changed, 159 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 21304fd..18247e7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2019-11-04 Martin Sebor <msebor@redhat.com>
+
+ 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 <rguenther@suse.de>
PR tree-optimization/92371
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 725cfa5..248d180 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2019-11-04 Martin Sebor <msebor@redhat.com>
+
+ 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 <rguenther@suse.de>
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 a4c4383..874aeee4 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 0000000..0f06222
--- /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 0000000..644fcd0
--- /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 3f10423..4486269 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 1328707..940ed9c 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. */