Commit 361d4a9e by Martin Sebor Committed by Martin Sebor

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
parent 02bf7e6f
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> 2019-11-05 Richard Biener <rguenther@suse.de>
PR tree-optimization/92371 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> 2019-11-05 Richard Biener <rguenther@suse.de>
PR tree-optimization/92371 PR tree-optimization/92371
......
...@@ -23,7 +23,7 @@ public: ...@@ -23,7 +23,7 @@ public:
virtual void set(unsigned long index, char value) { contents[index] = value; } virtual void set(unsigned long index, char value) { contents[index] = value; }
virtual char& operator[] (unsigned long index) { return contents[index]; } 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); void print_length (const String& string);
......
/* 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]'" }
}
/* 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" }
}
...@@ -3068,6 +3068,13 @@ get_access_for_expr (tree expr) ...@@ -3068,6 +3068,13 @@ get_access_for_expr (tree expr)
|| !DECL_P (base)) || !DECL_P (base))
return NULL; 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))) if (!bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
return NULL; return NULL;
......
...@@ -4083,18 +4083,18 @@ bool ...@@ -4083,18 +4083,18 @@ bool
vrp_prop::check_array_ref (location_t location, tree ref, vrp_prop::check_array_ref (location_t location, tree ref,
bool ignore_off_by_one) bool ignore_off_by_one)
{ {
tree low_sub, up_sub;
tree low_bound, up_bound, up_bound_p1;
if (TREE_NO_WARNING (ref)) if (TREE_NO_WARNING (ref))
return false; return false;
low_sub = up_sub = TREE_OPERAND (ref, 1); tree low_sub = TREE_OPERAND (ref, 1);
up_bound = array_ref_up_bound (ref); tree up_sub = low_sub;
tree up_bound = array_ref_up_bound (ref);
/* Set for accesses to interior zero-length arrays. */ /* Set for accesses to interior zero-length arrays. */
bool interior_zero_len = false; bool interior_zero_len = false;
tree up_bound_p1;
if (!up_bound if (!up_bound
|| TREE_CODE (up_bound) != INTEGER_CST || TREE_CODE (up_bound) != INTEGER_CST
|| (warn_array_bounds < 2 || (warn_array_bounds < 2
...@@ -4148,7 +4148,7 @@ vrp_prop::check_array_ref (location_t location, tree ref, ...@@ -4148,7 +4148,7 @@ vrp_prop::check_array_ref (location_t location, tree ref,
up_bound_p1 = int_const_binop (PLUS_EXPR, up_bound, up_bound_p1 = int_const_binop (PLUS_EXPR, up_bound,
build_int_cst (TREE_TYPE (up_bound), 1)); 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)); tree artype = TREE_TYPE (TREE_OPERAND (ref, 0));
...@@ -4157,8 +4157,8 @@ vrp_prop::check_array_ref (location_t location, tree ref, ...@@ -4157,8 +4157,8 @@ vrp_prop::check_array_ref (location_t location, tree ref,
/* Empty array. */ /* Empty array. */
if (up_bound && tree_int_cst_equal (low_bound, up_bound_p1)) if (up_bound && tree_int_cst_equal (low_bound, up_bound_p1))
warned = warning_at (location, OPT_Warray_bounds, warned = warning_at (location, OPT_Warray_bounds,
"array subscript %E is above array bounds of %qT", "array subscript %E is outside array bounds of %qT",
low_bound, artype); low_sub, artype);
const value_range_equiv *vr = NULL; const value_range_equiv *vr = NULL;
if (TREE_CODE (low_sub) == SSA_NAME) if (TREE_CODE (low_sub) == SSA_NAME)
...@@ -4372,6 +4372,7 @@ vrp_prop::check_mem_ref (location_t location, tree ref, ...@@ -4372,6 +4372,7 @@ vrp_prop::check_mem_ref (location_t location, tree ref,
{ {
arg = TREE_OPERAND (arg, 0); arg = TREE_OPERAND (arg, 0);
if (TREE_CODE (arg) != STRING_CST if (TREE_CODE (arg) != STRING_CST
&& TREE_CODE (arg) != PARM_DECL
&& TREE_CODE (arg) != VAR_DECL) && TREE_CODE (arg) != VAR_DECL)
return false; return false;
} }
...@@ -4455,7 +4456,9 @@ vrp_prop::check_mem_ref (location_t location, tree ref, ...@@ -4455,7 +4456,9 @@ vrp_prop::check_mem_ref (location_t location, tree ref,
if (ignore_off_by_one) if (ignore_off_by_one)
ubound += 1; 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 /* Treat a reference to a non-array object as one to an array
of a single element. */ of a single element. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment