Hi!
[Note: Jakub has mentioned that missing -Warray-bounds regressions
should be punted to GCC 9. I think this particular one is easy
pickings, but if this and/or the rest of the -Warray-bounds regressions
should be marked as GCC 9 material, please let me know so we can adjust
all relevant PRs.]
This is a -Warray-bounds regression that happens because the IL now has
an MEM_REF instead on ARRAY_REF.
Previously we had an ARRAY_REF we could diagnose:
D.2720_5 = "12345678"[1073741824];
But now this is represented as:
_1 = MEM[(const char *)"12345678" + 1073741824B];
I think we can just allow check_array_bounds() to handle MEM_REF's and
everything should just work.
The attached patch fixes both regressions mentioned in the PR.
Tested on x86-64 Linux.
OK?
gcc/
PR tree-optimization/84047
* tree-vrp.c (search_for_addr_array): Handle ADDR_EXPRs.
(check_array_bounds): Same.
diff --git a/gcc/testsuite/gcc.dg/pr84047.c b/gcc/testsuite/gcc.dg/pr84047.c
new file mode 100644
index 00000000000..9f9c6ca4a9e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr84047.c
@@ -0,0 +1,18 @@
+/* { dg-compile } */
+/* { dg-options "-O2 -Warray-bounds" } */
+
+int f (void)
+{
+ const char *s = "12345678";
+ int i = 1U << 30;
+ return s[i]; /* { dg-warning "array bounds" } */
+}
+
+char a[8];
+
+int g (void)
+{
+ const char *s = a + 4;
+ int i = 8;
+ return s[i]; /* { dg-warning "array bounds" } */
+}
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 3af81f70872..07d39bab8a4 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -4922,14 +4922,15 @@ void
vrp_prop::search_for_addr_array (tree t, location_t location)
{
/* Check each ARRAY_REFs in the reference chain. */
- do
- {
- if (TREE_CODE (t) == ARRAY_REF)
- check_array_ref (location, t, true /*ignore_off_by_one*/);
+ if (TREE_CODE (t) == ADDR_EXPR)
+ do
+ {
+ if (TREE_CODE (t) == ARRAY_REF)
+ check_array_ref (location, t, true /*ignore_off_by_one*/);
- t = TREE_OPERAND (t, 0);
- }
- while (handled_component_p (t));
+ t = TREE_OPERAND (t, 0);
+ }
+ while (handled_component_p (t));
if (TREE_CODE (t) == MEM_REF
&& TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR
@@ -5012,7 +5013,9 @@ check_array_bounds (tree *tp, int *walk_subtree, void *data)
if (TREE_CODE (t) == ARRAY_REF)
vrp_prop->check_array_ref (location, t, false /*ignore_off_by_one*/);
- else if (TREE_CODE (t) == ADDR_EXPR)
+ else if (TREE_CODE (t) == ADDR_EXPR
+ /* Handle (MEM_REF (ADDR_EXPR STRING_CST) INTEGER_CST). */
+ || TREE_CODE (t) == MEM_REF)
{
vrp_prop->search_for_addr_array (t, location);
*walk_subtree = FALSE;