From 14d83c6f584c321989b43526dc9437de4381aa47 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Wed, 14 Oct 2020 15:19:39 -0600 Subject: [PATCH] PR middle-end/97391 - bogus -Warray-bounds accessing a multidimensional array parameter 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 | 7 +- gcc/testsuite/gcc.dg/Warray-bounds-68.c | 118 ++++++++++++++++++++++++ 2 files changed, 120 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-68.c diff --git a/gcc/builtins.c b/gcc/builtins.c index 3f799e54d5f..72627b5b859 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -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 index 00000000000..d6616695471 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Warray-bounds-68.c @@ -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__; +} + + -- 2.30.2