PR middle-end/97391 - bogus -Warray-bounds accessing a multidimensional array parameter
authorMartin Sebor <msebor@redhat.com>
Wed, 14 Oct 2020 21:19:39 +0000 (15:19 -0600)
committerMartin Sebor <msebor@redhat.com>
Wed, 14 Oct 2020 21:36:24 +0000 (15:36 -0600)
gcc/ChangeLog:

PR middle-end/97391
* builtins.c (gimple_parm_array_size): Peel off one less layer
of array types.

gcc/testsuite/ChangeLog:

PR middle-end/97391
* gcc.dg/Warray-bounds-68.c: New test.

gcc/builtins.c
gcc/testsuite/gcc.dg/Warray-bounds-68.c [new file with mode: 0644]

index 3f799e54d5fe650bef08e0734adf0369c72e762f..72627b5b85947d9da74c9f3e76a6ec94ae07f111 100644 (file)
@@ -4493,12 +4493,9 @@ gimple_parm_array_size (tree ptr, wide_int rng[2],
 
   rng[0] = wi::zero (prec);
   rng[1] = wi::uhwi (access->minsize, prec);
-  /* If the PTR argument points to an array multiply MINSIZE by the size
-     of array element type.  Otherwise, multiply it by the size of what
-     the pointer points to.  */
+  /* Multiply the array bound encoded in the attribute by the size
+     of what the pointer argument to which it decays points to.  */
   tree eltype = TREE_TYPE (TREE_TYPE (ptr));
-  if (TREE_CODE (eltype) == ARRAY_TYPE)
-    eltype = TREE_TYPE (eltype);
   tree size = TYPE_SIZE_UNIT (eltype);
   if (!size || TREE_CODE (size) != INTEGER_CST)
     return NULL_TREE;
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-68.c b/gcc/testsuite/gcc.dg/Warray-bounds-68.c
new file mode 100644 (file)
index 0000000..d661669
--- /dev/null
@@ -0,0 +1,118 @@
+/* PR middle-end/97391 - bogus -Warray-bounds accessing a multidimensional
+   array parameter
+   { dg-do compile }
+   { dg-options "-O2 -Wall" } */
+
+
+void nowarn_access_loop_idx (char a[3][5])
+{
+  for (int i = 0; i < 3; i++)
+    for (int j = 0; j < 5; j++)
+      a[i][j] = 0;
+}
+
+void warn_access_loop_idx (char a[3][5])
+{
+  for (int i = 0; i < 3; i++)
+    for (int j = 0; j < 5; j++)
+      a[j][i] = 0;            // { dg-warning "\\\[-Warray-bounds" }
+}
+
+
+void nowarn_access_cst_idx (int a[5][7][9])
+{
+  a[0][0][0] = __LINE__;
+  a[0][0][8] = __LINE__;
+
+  a[0][6][0] = __LINE__;
+  a[0][6][8] = __LINE__;
+
+  a[4][0][0] = __LINE__;
+  a[4][0][8] = __LINE__;
+  a[4][6][8] = __LINE__;
+}
+
+
+void test_ptr_access_cst_idx (int a[5][7][9])
+{
+  int *p = &a[0][0][0];
+
+  p[0] = __LINE__;
+  p[8] = __LINE__;
+
+  /* The following access should trigger a warning but it's represented
+     the same  as the valid access in
+       p = a[0][1][0];
+       p[1] = __LINE__;
+     both as
+       MEM[(int *)a_1(D) + 36B] = __LINE__;  */
+
+  p[9] = __LINE__;            // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
+
+  p[315] = __LINE__;
+  // { dg-warning "subscript 315 is outside array bounds of 'int\\\[5]\\\[7]\\\[9]'" "pr97425" { xfail *-*-* } .-1 }
+  // { dg-warning "subscript 315 is outside array bounds " "" { target *-*-* } .-2 }
+
+  p = &a[0][6][0];
+  p[0] = __LINE__;
+  p[8] = __LINE__;
+
+  p = &a[4][6][0];
+  p[0] = __LINE__;
+  p[8] = __LINE__;
+}
+
+
+void warn_access_cst_idx (int a[5][7][9])
+{
+  a[0][0][9] = __LINE__;      // { dg-warning "subscript 9 is above array bounds of 'int\\\[9]'" }
+  a[0][7][0] = __LINE__;      // { dg-warning "subscript 7 is above array bounds of 'int\\\[7]\\\[9]'" }
+  a[5][0][0] = __LINE__;
+  // { dg-warning "subscript 5 is outside array bounds of 'int\\\[5]\\\[7]\\\[9]'" "pr97425" { xfail *-*-* } .-1 }
+  // { dg-warning "subscript \\d+ is outside array bounds" "" { target *-*-* } .-2 }
+}
+
+
+void test_ptrarray_access_cst_idx (int (*pa)[5][7][9])
+{
+  (*pa)[0][0][0] = __LINE__;
+  (*pa)[0][0][8] = __LINE__;
+  (*pa)[0][0][9] = __LINE__;  // { dg-warning "subscript 9 is above array bounds of 'int\\\[9]'" }
+
+  (*pa)[0][6][0] = __LINE__;
+  (*pa)[0][7][0] = __LINE__;  // { dg-warning "subscript 7 is above array bounds of 'int\\\[7]\\\[9]'" }
+  (*pa)[0][8][0] = __LINE__;  // { dg-warning "subscript 8 is above array bounds of 'int\\\[7]\\\[9]'" }
+
+  (*pa)[4][6][8] = __LINE__;
+  (*pa)[5][0][0] = __LINE__;  // { dg-warning "subscript 5 is above array bounds of 'int\\\[5]\\\[7]\\\[9]'" }
+}
+
+
+void test_ptr_ptrarray_access_cst_idx (int (*pa)[5][7][9])
+{
+  int *p = &(*pa)[0][0][0];
+
+  p[0] = __LINE__;
+  p[8] = __LINE__;
+
+  /* The following access should trigger a warning but it's represented
+     the same  as the valid access in
+       p = a[0][1][0];
+       p[1] = __LINE__;
+     both as
+       MEM[(int *)a_1(D) + 36B] = __LINE__;  */
+
+  p[9] = __LINE__;            // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
+
+  p[315] = __LINE__;          // { dg-warning "\\\[-Warray-bounds" "pr97429" { xfail *-*-* } }
+
+  p = &(*pa)[0][6][0];
+  p[0] = __LINE__;
+  p[8] = __LINE__;
+
+  p = &(*pa)[4][6][0];
+  p[0] = __LINE__;
+  p[8] = __LINE__;
+}
+
+