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
+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
+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
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);
--- /dev/null
+/* 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]'" }
+}
--- /dev/null
+/* 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" }
+}
|| !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;
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
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));
/* 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)
{
arg = TREE_OPERAND (arg, 0);
if (TREE_CODE (arg) != STRING_CST
+ && TREE_CODE (arg) != PARM_DECL
&& TREE_CODE (arg) != VAR_DECL)
return false;
}
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. */