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;

Reply via email to