public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-5871] Extend the offset and size of merged object references [PR103215].
@ 2021-12-09 19:51 Martin Sebor
0 siblings, 0 replies; only message in thread
From: Martin Sebor @ 2021-12-09 19:51 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:243a980437b5e7fca56587bf86667005bdf343a7
commit r12-5871-g243a980437b5e7fca56587bf86667005bdf343a7
Author: Martin Sebor <msebor@redhat.com>
Date: Thu Dec 9 12:49:28 2021 -0700
Extend the offset and size of merged object references [PR103215].
Resolves:
PR tree-optimization/103215 - bogus -Warray-bounds with two pointers with different offsets each
gcc/ChangeLog:
PR tree-optimization/103215
* pointer-query.cc (access_ref::merge_ref): Extend the offset and
size of the merged object instead of using the larger.
gcc/testsuite/ChangeLog:
PR tree-optimization/103215
* gcc.dg/Wstringop-overflow-58.c: Adjust and xfail expected warnings.
* gcc.dg/Wstringop-overflow-59.c: Same.
* gcc.dg/warn-strnlen-no-nul.c: Same.
* gcc.dg/Warray-bounds-91.c: New test.
* gcc.dg/Warray-bounds-92.c: New test.
* gcc.dg/Wstringop-overflow-85.c: New test.
* gcc.dg/Wstringop-overflow-87.c: New test.
Diff:
---
gcc/pointer-query.cc | 33 +++---
gcc/testsuite/gcc.dg/Warray-bounds-91.c | 145 +++++++++++++++++++++++++
gcc/testsuite/gcc.dg/Warray-bounds-92.c | 149 ++++++++++++++++++++++++++
gcc/testsuite/gcc.dg/Wstringop-overflow-58.c | 22 ++--
gcc/testsuite/gcc.dg/Wstringop-overflow-59.c | 18 +++-
gcc/testsuite/gcc.dg/Wstringop-overflow-85.c | 153 +++++++++++++++++++++++++++
gcc/testsuite/gcc.dg/Wstringop-overflow-87.c | 147 +++++++++++++++++++++++++
gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c | 43 ++++----
8 files changed, 664 insertions(+), 46 deletions(-)
diff --git a/gcc/pointer-query.cc b/gcc/pointer-query.cc
index e618c4d7276..4bedf7fca47 100644
--- a/gcc/pointer-query.cc
+++ b/gcc/pointer-query.cc
@@ -688,27 +688,32 @@ access_ref::merge_ref (vec<access_ref> *all_refs, tree arg, gimple *stmt,
if (known_size && aref.sizrng[0] < minsize)
minsize = aref.sizrng[0];
- /* Determine the amount of remaining space in the argument. */
- offset_int argrem[2];
- argrem[1] = aref.size_remaining (argrem);
+ /* Extend the size and offset of *THIS to account for AREF. The result
+ can be cached but results in false negatives. */
- /* Determine the amount of remaining space computed so far and
- if the remaining space in the argument is more use it instead. */
- offset_int merged_rem[2];
- merged_rem[1] = size_remaining (merged_rem);
+ offset_int orng[2];
+ if (sizrng[1] < aref.sizrng[1])
+ {
+ orng[0] = offrng[0];
+ orng[1] = offrng[1];
+ *this = aref;
+ }
+ else
+ {
+ orng[0] = aref.offrng[0];
+ orng[1] = aref.offrng[1];
+ }
+
+ if (orng[0] < offrng[0])
+ offrng[0] = orng[0];
+ if (offrng[1] < orng[1])
+ offrng[1] = orng[1];
/* Reset the PHI's BASE0 flag if any of the nonnull arguments
refers to an object at an unknown offset. */
if (!aref.base0)
base0 = false;
- if (merged_rem[1] < argrem[1]
- || (merged_rem[1] == argrem[1]
- && sizrng[1] < aref.sizrng[1]))
- /* Use the argument with the most space remaining as the result,
- or the larger one if the space is equal. */
- *this = aref;
-
sizrng[0] = minsize;
parmarray = merged_parmarray;
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-91.c b/gcc/testsuite/gcc.dg/Warray-bounds-91.c
new file mode 100644
index 00000000000..1c81091b2a6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-91.c
@@ -0,0 +1,145 @@
+/* PR middle-end/103215 - bogus -Warray-bounds with two pointers with
+ different offsets each
+ Test for accesses into the same array through pointers with different
+ offsets each.
+ { dg-do compile }
+ { dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */
+
+#define NOIPA __attribute__ ((noipa))
+
+#define A(p, off) ((p)[off] = __COUNTER__)
+
+extern int a4[4];
+
+
+NOIPA void p0_p1 (int i)
+{
+ int *p0 = a4 + 0;
+ int *p1 = a4 + 1;
+ int *q = i ? p0 : p1;
+ A (q, -2); // { dg-warning "-Warray-bounds" }
+ A (q, -1); A (q, 0); A (q, 1); A (q, 2);
+ /* Since q points to a4 and -1 is a valid subscript, +3 must be invalid.
+ But the warning for each subscript is independent of prior subscripts
+ into the same object. That should be improved. */
+ A (q, 3); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 4); // { dg-warning "-Warray-bounds" }
+}
+
+NOIPA void p1_p0 (int i)
+{
+ int *p1 = a4 + 1;
+ int *p0 = a4 + 0;
+ int *q = i ? p0 : p1;
+ A (q, -2); // { dg-warning "-Warray-bounds" }
+ A (q, -1); A (q, 0); A (q, 1); A (q, 2);
+ A (q, 3); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 4); // { dg-warning "-Warray-bounds" }
+}
+
+
+NOIPA void p1_p2 (int i)
+{
+ int *p1 = a4 + 1;
+ int *p2 = a4 + 2;
+ int *q = i ? p1 : p2;
+ A (q, -3); // { dg-warning "-Warray-bounds" }
+ A (q, -2); A (q, -1); A (q, 0); A (q, 1);
+ A (q, 2); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 3); // { dg-warning "-Warray-bounds" }
+}
+
+NOIPA void p2_p1 (int i)
+{
+ int *p2 = a4 + 2;
+ int *p1 = a4 + 1;
+ int *q = i ? p1 : p2;
+ A (q, -3); // { dg-warning "-Warray-bounds" }
+ A (q, -2); A (q, -1); A (q, 0); A (q, 1);
+ A (q, 2); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 3); // { dg-warning "-Warray-bounds" }
+}
+
+
+NOIPA void p1_p3 (int i)
+{
+ int *p1 = a4 + 1;
+ int *p3 = a4 + 3;
+ int *q = i ? p1 : p3;
+ A (q, -4); // { dg-warning "-Warray-bounds" }
+ A (q, -3); A (q, -2); A (q, -1); A (q, 0);
+ A (q, 1); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 2); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 3); // { dg-warning "-Warray-bounds" }
+}
+
+NOIPA void p3_p1 (int i)
+{
+ int *p3 = a4 + 3;
+ int *p1 = a4 + 1;
+ int *q = i ? p1 : p3;
+ A (q, -4); // { dg-warning "-Warray-bounds" }
+ A (q, -3); A (q, -2); A (q, -1); A (q, 0);
+ A (q, 1); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 2); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 3); // { dg-warning "-Warray-bounds" }
+}
+
+
+NOIPA void p1_p4 (int i)
+{
+ int *p1 = a4 + 1;
+ int *p4 = a4 + 4;
+ int *q = i ? p1 : p4;
+ A (q, -5); // { dg-warning "-Warray-bounds" }
+ A (q, -4); A (q, -3); A (q, -2); A (q, -1);
+ A (q, 0); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 1); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 2); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 3); // { dg-warning "-Warray-bounds" }
+}
+
+NOIPA void p4_p1 (int i)
+{
+ int *p4 = a4 + 4;
+ int *p1 = a4 + 1;
+ int *q = i ? p1 : p4;
+ A (q, -5); // { dg-warning "-Warray-bounds" }
+ A (q, -4); A (q, -3); A (q, -2); A (q, -1);
+ A (q, 0); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 1); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 2); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 3); // { dg-warning "-Warray-bounds" }
+}
+
+
+NOIPA void p0_p1_p2 (int i)
+{
+ int *p0 = a4 + 0;
+ int *p1 = a4 + 1;
+ int *p2 = a4 + 2;
+ int *q = i < 0 ? p1 : 0 < i ? p2 : p0;
+ A (q, -3); // { dg-warning "-Warray-bounds" }
+ A (q, -2); A (q, -1); A (q, 0); A (q, 1);
+ A (q, 2); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 3); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 4); // { dg-warning "-Warray-bounds" }
+}
+
+
+NOIPA void p0_p1_p2_p3_p4 (int i)
+{
+ int *p0 = a4 + 0;
+ int *p1 = a4 + 1;
+ int *p2 = a4 + 2;
+ int *p3 = a4 + 3;
+ int *p4 = a4 + 4;
+ int *q = i < -1 ? p1 : i < 0 ? p2 : 1 < i ? p4 : 0 < i ? p3 : p0;
+ A (q, -5); // { dg-warning "-Warray-bounds" }
+ A (q, -4); A (q, -3); A (q, -2); A (q, -1);
+ A (q, 0); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 1); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 2); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 3); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 4); // { dg-warning "-Warray-bounds" }
+}
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-92.c b/gcc/testsuite/gcc.dg/Warray-bounds-92.c
new file mode 100644
index 00000000000..8c8f5f7f459
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-92.c
@@ -0,0 +1,149 @@
+/* PR middle-end/103215 - bogus -Warray-bounds with two pointers with
+ different offsets each
+ Test for accesses into distinct arrays through pointers with different
+ offsets each.
+
+ If/when -Warray-bounds is enhanced to issue "maybe" kinds of warnings
+ some of the accesses here will trigger those and will need updating.
+
+ { dg-do compile }
+ { dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */
+
+#define NOIPA __attribute__ ((noipa))
+
+#define A(p, off) ((p)[off] = __COUNTER__)
+
+extern int a4[4], a8[8];
+
+
+NOIPA void a4_p1_a8_p3 (int i)
+{
+ int *a4_p1 = a4 + 1;
+ int *a8_p3 = a8 + 3;
+ int *q = i ? a4_p1 : a8_p3;
+ A (q, -4); // { dg-warning "-Warray-bounds" }
+ /* Because -3 is a valid offset into a8 but not a4, q must point
+ to the former and so subscripts between -3 and +4 refer to its
+ elements. */
+ A (q, -3); A (q, -2); A (q, -1); A (q, 0);
+ A (q, 1); A (q, 2); A (q, 3); A (q, 4);
+ A (q, 5); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ /* Both of the following are definitely out of bounds but the first isn't
+ diagnosed because the code conservatively merges the offsets into A4
+ and A8. */
+ A (q, 7); // { dg-warning "-Warray-bounds" }
+}
+
+
+NOIPA void a4_p1_a8_p5 (int i)
+{
+ int *a4_p1 = a4 + 1;
+ int *a8_p5 = a8 + 5;
+ int *q = i ? a4_p1 : a8_p5;
+ A (q, -6); // { dg-warning "-Warray-bounds" }
+ /* Similarly to the above, because -5 is a valid offset into a8 but
+ not a4, q must point to the former and so subscripts between -5
+ and +2 refer to its elements. */
+ A (q, -5); A (q, -4); A (q, -3); A (q, -2);
+ A (q, -1); A (q, 0); A (q, 1); A (q, 2);
+ A (q, 3); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 7); // { dg-warning "-Warray-bounds" }
+}
+
+
+NOIPA void a4_p1_a8_p7 (int i)
+{
+ int *a4_p1 = a4 + 1;
+ int *a8_p7 = a8 + 7;
+ int *q = i ? a4_p1 : a8_p7;
+ A (q, -8); // { dg-warning "-Warray-bounds" }
+ A (q, -7); A (q, -6); A (q, -5); A (q, -4);
+ A (q, -3); A (q, -2); A (q, -1); A (q, 0);
+ /* Since -7 is valid, q must point to a8 and the last valid subscript
+ must be 0. */
+ A (q, 1); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 2); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 3); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 7); // { dg-warning "-Warray-bounds" }
+}
+
+
+NOIPA void mp_1_a4_p1_a8_p7 (int i, int j)
+{
+ int *a4_p1 = a4 + 1;
+ int *a8_p7 = a8 + 7;
+ int *p = i ? a4_p1 : a8_p7;
+ int *q = j ? p + 1 : p - 1;
+
+ A (q, -9); // { dg-warning "-Warray-bounds" }
+
+ /* q points either to a8 + [6, 8] or a4 + [0, 2]. */
+ A (q, -8); A (q, -7); A (q, -6); A (q, -5);
+ A (q, -4); A (q, -3); A (q, -2); A (q, -1);
+
+ /* Since all the above are valid, q must point to a8 + 8. But as
+ mentioned above, the warning for each subscript is independent
+ of prior subscripts into the same object so the access below
+ aren't diagnosed. */
+ A (q, 0); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 1); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 2); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 3); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 4); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 8); // { dg-warning "-Warray-bounds" }
+}
+
+
+NOIPA void mp1_a4_p1_a8_p5 (int i, int j)
+{
+ int *a4_p1 = a4 + 1;
+ int *a8_p5 = a8 + 5;
+ int *p = i ? a4_p1 : a8_p5;
+
+ int *q = j ? p + 1 : p - 1;
+
+ // q is assumed to point to a8 + 6
+ A (q, -7); // { dg-warning "-Warray-bounds" }
+ A (q, -6); A (q, -5); A (q, -4); A (q, -3);
+ A (q, -2); A (q, -1); A (q, 0); A (q, 1);
+ /* Even though the above accesses rule it out, q is now assumed
+ to point to either a4 + [0, 2] or a8 + [4, 5]. */
+ A (q, 2);
+ /* q is now assumed to point tp a4. Given that, only the first store
+ is valid. */
+ A (q, 3); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 4); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 5); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 6); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 7); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 8); // { dg-warning "-Warray-bounds" }
+}
+
+
+NOIPA void mp1_a4_p1_a8_p4 (int i, int j)
+{
+ int *a4_p1 = a4 + 1;
+ int *a8_p4 = a8 + 4;
+ int *p = i ? a4_p1 : a8_p4;
+
+ int *q = j ? p + 1 : p - 1;
+
+ // q is assumed to point to a8 + 5
+ A (q, -6); // { dg-warning "-Warray-bounds" }
+ A (q, -5);
+ A (q, -4);
+ A (q, -3);
+ A (q, -2);
+ A (q, -1);
+ A (q, 0);
+ A (q, 1);
+ A (q, 2);
+ /* Even though the above accesses rule it out, q is now assumed
+ to point tp a4. Given that, only the first store is valid. */
+ A (q, 3); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 4); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 5); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 6); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 7); // { dg-warning "-Warray-bounds" "pr??????" { xfail *-*-* } }
+ A (q, 8); // { dg-warning "-Warray-bounds" }
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-58.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-58.c
index b81186cfb94..e0a40788f0d 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-58.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-58.c
@@ -182,8 +182,8 @@ void memset_decl_2_off (void)
int i2 = SR (2, INT_MAX);
{
- char a5[5]; // { dg-warning "at offset [1, 5] into destination object 'a5'
- char a7[7]; // { dg-warning "at offset [2, 7] into destination object 'a7'
+ char a5[5]; // { dg-message "at offset \\\[1, 5] into destination object 'a5'" "note" }
+ char a7[7]; // { dg-message "at offset \\\[2, 7] into destination object 'a7'" "note" }
char *p5_p1 = a5 + i1;
char *p7_p2 = a7 + i2;
char *p5_7 = cond1 ? p5_p1 : p7_p2;
@@ -193,7 +193,11 @@ void memset_decl_2_off (void)
memset (p5_7, 0, 3);
memset (p5_7, 0, 4);
memset (p5_7, 0, 5);
- memset (p5_7, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5 " }
+ /* The warning code conservatively "merges" both the sizes and the offsets
+ into A5 and A7 and so only the second store below is diagnosed but not
+ the first. See PR 103215. The logic needs to be tightened up. */
+ memset (p5_7, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5 " "pr??????" { xfail *-*-* } }
+ memset (p5_7, 0, 7); // { dg-warning "memset' writing 7 bytes into a region of size 6 " }
}
int i3 = SR (3, INT_MAX);
@@ -208,7 +212,8 @@ void memset_decl_2_off (void)
// { dg-message "at offset \\\[4, 9] into destination object 'a9'" "note" { target *-*-* } .-1 }
// { dg-message "at offset \\\[3, 9] into destination object 'a9'" "note" { target *-*-* } .-2 }
// { dg-message "at offset \\\[2, 9] into destination object 'a9'" "note" { target *-*-* } .-3 }
- // { dg-message ": destination object 'a9'" "note" { target *-*-* } .-4 }
+ // { dg-message "at offset \\\[1, 9] into destination object 'a9'" "note" { target *-*-* } .-4 }
+ // { dg-message ": destination object 'a9'" "pr??????" { xfail *-*-* } .-5 }
char *p5_p2 = a5 + i2; // 3 bytes left
char *p9_p3 = a9 + i3; // 6 bytes left
char *p =
@@ -220,7 +225,8 @@ void memset_decl_2_off (void)
memset (q, 0, 3);
memset (q, 0, 4);
memset (q, 0, 5);
- memset (q, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5" }
+ memset (q, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5" "pr??????" { xfail *-*-* } }
+ memset (q, 0, 7); // { dg-warning "memset' writing 7 bytes into a region of size 6" }
--q; // [3 - 6] bytes left
memset (q, 0, 1);
@@ -229,7 +235,8 @@ void memset_decl_2_off (void)
memset (q, 0, 4);
memset (q, 0, 5);
memset (q, 0, 6);
- memset (q, 0, 7); // { dg-warning "memset' writing 7 bytes into a region of size 6" }
+ memset (q, 0, 7); // { dg-warning "memset' writing 7 bytes into a region of size 6" "pr??????" { xfail *-*-* } }
+ memset (q, 0, 8); // { dg-warning "memset' writing 8 bytes into a region of size 7" }
--q; // [4 - 7] bytes left
memset (q, 0, 1);
@@ -239,7 +246,8 @@ void memset_decl_2_off (void)
memset (q, 0, 5);
memset (q, 0, 6);
memset (q, 0, 7);
- memset (q, 0, 8); // { dg-warning "memset' writing 8 bytes into a region of size 7" }
+ memset (q, 0, 8); // { dg-warning "memset' writing 8 bytes into a region of size 7" "pr??????" { xfail *-*-* } }
+ memset (q, 0, 9); // { dg-warning "memset' writing 9 bytes into a region of size 8" }
int m1_x = SR (-1, INT_MAX);
int m2_x = SR (-2, INT_MAX);
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-59.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-59.c
index c45a92d21e1..b6265e37c86 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-59.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-59.c
@@ -200,7 +200,11 @@ void memset_malloc_2_off (void)
memset (p5_7, 0, 3);
memset (p5_7, 0, 4);
memset (p5_7, 0, 5);
- memset (p5_7, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5 " }
+ /* The warning code conservatively "merges" both the sizes and the offsets
+ into A5 and A7 and so only the second store below is diagnosed but not
+ the first. See PR 103215. The logic needs to be tightened up. */
+ memset (p5_7, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5 " "pr??????" { xfail *-*-* } }
+ memset (p5_7, 0, 7); // { dg-warning "memset' writing 7 bytes into a region of size 6 " }
}
int i3 = SR (3, INT_MAX);
@@ -215,7 +219,8 @@ void memset_malloc_2_off (void)
// { dg-message "at offset \\\[4, 9] into destination object 'a9'" "note" { target *-*-* } .-1 }
// { dg-message "at offset \\\[3, 9] into destination object 'a9'" "note" { target *-*-* } .-2 }
// { dg-message "at offset \\\[2, 9] into destination object 'a9'" "note" { target *-*-* } .-3 }
- // { dg-message ": destination object 'a9'" "note" { target *-*-* } .-4 }
+ // { dg-message "at offset \\\[1, 9] into destination object 'a9'" "note" { target *-*-* } .-4 }
+ // { dg-message ": destination object 'a9'" "pr??????" { xfail *-*-* } .-5 }
char *p5_p2 = a5 + i2; // 3 bytes left
char *p9_p3 = a9 + i3; // 6 bytes left
char *p =
@@ -227,7 +232,8 @@ void memset_malloc_2_off (void)
memset (q, 0, 3);
memset (q, 0, 4);
memset (q, 0, 5);
- memset (q, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5" }
+ memset (q, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5" "pr??????" { xfail *-*-* } }
+ memset (q, 0, 7); // { dg-warning "memset' writing 7 bytes into a region of size 6" }
--q; // [3 - 6] bytes left
memset (q, 0, 1);
@@ -236,7 +242,8 @@ void memset_malloc_2_off (void)
memset (q, 0, 4);
memset (q, 0, 5);
memset (q, 0, 6);
- memset (q, 0, 7); // { dg-warning "memset' writing 7 bytes into a region of size 6" }
+ memset (q, 0, 7); // { dg-warning "memset' writing 7 bytes into a region of size 6" "pr??????" { xfail *-*-* } }
+ memset (q, 0, 8); // { dg-warning "memset' writing 8 bytes into a region of size 7" }
--q; // [4 - 7] bytes left
memset (q, 0, 1);
@@ -246,7 +253,8 @@ void memset_malloc_2_off (void)
memset (q, 0, 5);
memset (q, 0, 6);
memset (q, 0, 7);
- memset (q, 0, 8); // { dg-warning "memset' writing 8 bytes into a region of size 7" }
+ memset (q, 0, 8); // { dg-warning "memset' writing 8 bytes into a region of size 7" "pr??????" { xfail *-*-* } }
+ memset (q, 0, 9); // { dg-warning "memset' writing 9 bytes into a region of size 8" }
int m1_x = SR (-1, INT_MAX);
int m2_x = SR (-2, INT_MAX);
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-85.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-85.c
new file mode 100644
index 00000000000..ac61e0a0a64
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-85.c
@@ -0,0 +1,153 @@
+/* PR middle-end/103215 - bogus -Wstringop-overflow with two pointers with
+ different offsets each
+ Test for accesses into distinct arrays through pointers with different
+ offsets each.
+
+ If/when -Wstringop-overflow is enhanced to issue "maybe" kinds of
+ warnings some of the accesses here will trigger those and will need
+ updating.
+
+ { dg-do compile }
+ { dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */
+
+#define NOIPA __attribute__ ((noipa))
+
+void sink (int[1]);
+#define A(p, off) sink (p + off)
+
+extern int a4[4], a8[8];
+
+
+
+
+NOIPA void a4_p1_a8_p3 (int i)
+{
+ int *a4_p1 = a4 + 1;
+ int *a8_p3 = a8 + 3;
+ int *q = i ? a4_p1 : a8_p3;
+ A (q, -4); // { dg-warning "-Wstringop-overflow" }
+ /* Because -3 is a valid offset into a8 but not a4, q must point
+ to the former and so subscripts between -3 and +4 refer to its
+ elements. */
+ A (q, -3); A (q, -2); A (q, -1); A (q, 0);
+ A (q, 1); A (q, 2); A (q, 3); A (q, 4);
+ A (q, 5); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ /* Both of the following are definitely out of bounds but the first isn't
+ diagnosed because the code conservatively merges the offsets into A4
+ and A8. */
+ A (q, 7); // { dg-warning "-Wstringop-overflow" }
+}
+
+
+NOIPA void a4_p1_a8_p5 (int i)
+{
+ int *a4_p1 = a4 + 1;
+ int *a8_p5 = a8 + 5;
+ int *q = i ? a4_p1 : a8_p5;
+ A (q, -6); // { dg-warning "-Wstringop-overflow" }
+ /* Similarly to the above, because -5 is a valid offset into a8 but
+ not a4, q must point to the former and so subscripts between -5
+ and +2 refer to its elements. */
+ A (q, -5); A (q, -4); A (q, -3); A (q, -2);
+ A (q, -1); A (q, 0); A (q, 1); A (q, 2);
+ A (q, 3); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 7); // { dg-warning "-Wstringop-overflow" }
+}
+
+
+NOIPA void a4_p1_a8_p7 (int i)
+{
+ int *a4_p1 = a4 + 1;
+ int *a8_p7 = a8 + 7;
+ int *q = i ? a4_p1 : a8_p7;
+ A (q, -8); // { dg-warning "-Wstringop-overflow" }
+ A (q, -7); A (q, -6); A (q, -5); A (q, -4);
+ A (q, -3); A (q, -2); A (q, -1); A (q, 0);
+ /* Since -7 is valid, q must point to a8 and the last valid subscript
+ must be 0. */
+ A (q, 1); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 2); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 3); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 7); // { dg-warning "-Wstringop-overflow" }
+}
+
+
+NOIPA void mp_1_a4_p1_a8_p7 (int i, int j)
+{
+ int *a4_p1 = a4 + 1;
+ int *a8_p7 = a8 + 7;
+ int *p = i ? a4_p1 : a8_p7;
+ int *q = j ? p + 1 : p - 1;
+
+ A (q, -9); // { dg-warning "-Wstringop-overflow" }
+
+ /* q points either to a8 + [6, 8] or a4 + [0, 2]. */
+ A (q, -8); A (q, -7); A (q, -6); A (q, -5);
+ A (q, -4); A (q, -3); A (q, -2); A (q, -1);
+
+ /* Since all the above are valid, q must point to a8 + 8. But as
+ mentioned above, the warning for each subscript is independent
+ of prior subscripts into the same object so the access below
+ aren't diagnosed. */
+ A (q, 0); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 1); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 2); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 3); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 4); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 8); // { dg-warning "-Wstringop-overflow" }
+}
+
+
+NOIPA void mp1_a4_p1_a8_p5 (int i, int j)
+{
+ int *a4_p1 = a4 + 1;
+ int *a8_p5 = a8 + 5;
+ int *p = i ? a4_p1 : a8_p5;
+
+ int *q = j ? p + 1 : p - 1;
+
+ // q is assumed to point to a8 + 6
+ A (q, -7); // { dg-warning "-Wstringop-overflow" }
+ A (q, -6); A (q, -5); A (q, -4); A (q, -3);
+ A (q, -2); A (q, -1); A (q, 0); A (q, 1);
+ /* Even though the above accesses rule it out, q is now assumed
+ to point to either a4 + [0, 2] or a8 + [4, 5]. */
+ A (q, 2);
+ /* q is now assumed to point tp a4. Given that, only the first store
+ is valid. */
+ A (q, 3); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 4); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 5); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 6); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 7); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 8); // { dg-warning "-Wstringop-overflow" }
+}
+
+
+NOIPA void mp1_a4_p1_a8_p4 (int i, int j)
+{
+ int *a4_p1 = a4 + 1;
+ int *a8_p4 = a8 + 4;
+ int *p = i ? a4_p1 : a8_p4;
+
+ int *q = j ? p + 1 : p - 1;
+
+ // q is assumed to point to a8 + 5
+ A (q, -6); // { dg-warning "-Wstringop-overflow" }
+ A (q, -5);
+ A (q, -4);
+ A (q, -3);
+ A (q, -2);
+ A (q, -1);
+ A (q, 0);
+ A (q, 1);
+ A (q, 2);
+ /* Even though the above accesses rule it out, q is now assumed
+ to point tp a4. Given that, only the first store is valid. */
+ A (q, 3); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 4); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 5); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 6); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 7); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 8); // { dg-warning "-Wstringop-overflow" }
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-87.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-87.c
new file mode 100644
index 00000000000..bc121928f1b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-87.c
@@ -0,0 +1,147 @@
+/* PR middle-end/103215 - bogus -Warray-bounds with two pointers with
+ different offsets each
+ Test for accesses by a user-defined function into the same array
+ through pointers with different offsets each. See Warray-bounds-91.c
+ for the corresponding test exercising -Warray-bounds for direct accesses.
+ { dg-do compile }
+ { dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */
+
+#define NOIPA __attribute__ ((noipa))
+
+void sink (int[1]);
+#define A(p, off) sink (p + off)
+
+extern int a4[4];
+
+
+NOIPA void p0_p1 (int i)
+{
+ int *p0 = a4 + 0;
+ int *p1 = a4 + 1;
+ int *q = i ? p0 : p1;
+ A (q, -2); // { dg-warning "-Wstringop-overflow" }
+ A (q, -1); A (q, 0); A (q, 1); A (q, 2);
+ /* Since q points to a4 and -1 is a valid subscript, +3 must be invalid.
+ But the warning for each subscript is independent of prior subscripts
+ into the same object. That should be improved. */
+ A (q, 3); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 4); // { dg-warning "-Wstringop-overflow" }
+}
+
+NOIPA void p1_p0 (int i)
+{
+ int *p1 = a4 + 1;
+ int *p0 = a4 + 0;
+ int *q = i ? p0 : p1;
+ A (q, -2); // { dg-warning "-Wstringop-overflow" }
+ A (q, -1); A (q, 0); A (q, 1); A (q, 2);
+ A (q, 3); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 4); // { dg-warning "-Wstringop-overflow" }
+}
+
+
+NOIPA void p1_p2 (int i)
+{
+ int *p1 = a4 + 1;
+ int *p2 = a4 + 2;
+ int *q = i ? p1 : p2;
+ A (q, -3); // { dg-warning "-Wstringop-overflow" }
+ A (q, -2); A (q, -1); A (q, 0); A (q, 1);
+ A (q, 2); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 3); // { dg-warning "-Wstringop-overflow" }
+}
+
+NOIPA void p2_p1 (int i)
+{
+ int *p2 = a4 + 2;
+ int *p1 = a4 + 1;
+ int *q = i ? p1 : p2;
+ A (q, -3); // { dg-warning "-Wstringop-overflow" }
+ A (q, -2); A (q, -1); A (q, 0); A (q, 1);
+ A (q, 2); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 3); // { dg-warning "-Wstringop-overflow" }
+}
+
+
+NOIPA void p1_p3 (int i)
+{
+ int *p1 = a4 + 1;
+ int *p3 = a4 + 3;
+ int *q = i ? p1 : p3;
+ A (q, -4); // { dg-warning "-Wstringop-overflow" }
+ A (q, -3); A (q, -2); A (q, -1); A (q, 0);
+ A (q, 1); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 2); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 3); // { dg-warning "-Wstringop-overflow" }
+}
+
+NOIPA void p3_p1 (int i)
+{
+ int *p3 = a4 + 3;
+ int *p1 = a4 + 1;
+ int *q = i ? p1 : p3;
+ A (q, -4); // { dg-warning "-Wstringop-overflow" }
+ A (q, -3); A (q, -2); A (q, -1); A (q, 0);
+ A (q, 1); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 2); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 3); // { dg-warning "-Wstringop-overflow" }
+}
+
+
+NOIPA void p1_p4 (int i)
+{
+ int *p1 = a4 + 1;
+ int *p4 = a4 + 4;
+ int *q = i ? p1 : p4;
+ A (q, -5); // { dg-warning "-Wstringop-overflow" }
+ A (q, -4); A (q, -3); A (q, -2); A (q, -1);
+ A (q, 0); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 1); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 2); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 3); // { dg-warning "-Wstringop-overflow" }
+}
+
+NOIPA void p4_p1 (int i)
+{
+ int *p4 = a4 + 4;
+ int *p1 = a4 + 1;
+ int *q = i ? p1 : p4;
+ A (q, -5); // { dg-warning "-Wstringop-overflow" }
+ A (q, -4); A (q, -3); A (q, -2); A (q, -1);
+ A (q, 0); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 1); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 2); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 3); // { dg-warning "-Wstringop-overflow" }
+}
+
+
+NOIPA void p0_p1_p2 (int i)
+{
+ int *p0 = a4 + 0;
+ int *p1 = a4 + 1;
+ int *p2 = a4 + 2;
+ int *q = i < 0 ? p1 : 0 < i ? p2 : p0;
+ A (q, -3); // { dg-warning "-Wstringop-overflow" }
+ A (q, -2); A (q, -1); A (q, 0); A (q, 1);
+ A (q, 2); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 3); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 4); // { dg-warning "-Wstringop-overflow" }
+}
+
+
+NOIPA void p0_p1_p2_p3_p4 (int i)
+{
+ int *p0 = a4 + 0;
+ int *p1 = a4 + 1;
+ int *p2 = a4 + 2;
+ int *p3 = a4 + 3;
+ int *p4 = a4 + 4;
+ int *q = i < -1 ? p1 : i < 0 ? p2 : 1 < i ? p4 : 0 < i ? p3 : p0;
+ A (q, -5); // { dg-warning "-Wstringop-overflow" }
+ A (q, -4); A (q, -3); A (q, -2); A (q, -1);
+ A (q, 0); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 1); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 2); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 3); // { dg-warning "-Wstringop-overflow" "pr??????" { xfail *-*-* } }
+ A (q, 4); // { dg-warning "-Wstringop-overflow" }
+}
diff --git a/gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c b/gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c
index 846e9300750..70f6a432b97 100644
--- a/gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c
+++ b/gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c
@@ -143,17 +143,18 @@ T (v0 ? b[1] : "", bsz);
T (v0 ? b[2] : "", bsz);
T (v0 ? b[3] : "", bsz);
-/* The warnings below are strictly correct but the strnlen calls are safe
- because the reads are bounded by the length of the constant arguments.
- It might make sense to relax the warning to avoid triggering for them. */
+/* Warning for the calls below would be strictly correct even though
+ the strnlen calls are safe because the reads are bounded by
+ the length of the constant arguments. Most of the calls are
+ not diagnosed anymore as a result of the fix for PR 103215. */
T (v0 ? "" : b[0], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */
-T (v0 ? "" : b[1], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */
-T (v0 ? "" : b[2], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */
-T (v0 ? "" : b[3], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */
+T (v0 ? "" : b[1], bsz + 1);
+T (v0 ? "" : b[2], bsz + 1);
+T (v0 ? "" : b[3], bsz + 1);
T (v0 ? b[0] : "", bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */
-T (v0 ? b[1] : "", bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */
-T (v0 ? b[2] : "", bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */
-T (v0 ? b[3] : "", bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */
+T (v0 ? b[1] : "", bsz + 1);
+T (v0 ? b[2] : "", bsz + 1);
+T (v0 ? b[3] : "", bsz + 1);
T (v0 ? "" : b[i0], bsz);
T (v0 ? "" : b[i1], bsz);
@@ -167,11 +168,11 @@ T (v0 ? b[i3] : "", bsz);
T (v0 ? "" : b[i0], bsz + 1);
T (v0 ? "" : b[i1], bsz + 1);
T (v0 ? "" : b[i2], bsz + 1);
-T (v0 ? "" : b[i3], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" "pr86937" } */
+T (v0 ? "" : b[i3], bsz + 1);
T (v0 ? b[i0] : "", bsz + 1);
T (v0 ? b[i1] : "", bsz + 1);
T (v0 ? b[i2] : "", bsz + 1);
-T (v0 ? b[i3] : "", bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" "pr86937" } */
+T (v0 ? b[i3] : "", bsz + 1);
T (v0 ? "1234" : b[3], bsz);
T (v0 ? "1234" : b[i3], bsz);
@@ -183,15 +184,17 @@ T (v0 ? b[0] : b[2], bsz);
T (v0 ? b[2] : b[3], bsz);
T (v0 ? b[3] : b[2], bsz);
-T (v0 ? "1234" : b[3], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */
-T (v0 ? "1234" : b[i3], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */
-T (v0 ? b[3] : "1234", bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */
-T (v0 ? b[i3] : "1234", bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */
-
-T (v0 ? a : b[3], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */
-T (v0 ? b[0] : b[2], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */
-T (v0 ? b[2] : b[3], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */
-T (v0 ? b[3] : b[2], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" } */
+T (v0 ? "1234" : b[3], bsz + 1);
+T (v0 ? "1234" : b[i3], bsz + 1);
+T (v0 ? b[3] : "1234", bsz + 1);
+T (v0 ? b[i3] : "1234", bsz + 1);
+
+/* That the following are not diagnosed is a bug/limitation resulting from
+ the fix for PR 103215. */
+T (v0 ? a : b[3], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" "pr103215" { xfail *-*-* } } */
+T (v0 ? b[0] : b[2], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" "pr103215" { xfail *-*-* } } */
+T (v0 ? b[2] : b[3], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" "pr103215" { xfail *-*-* } } */
+T (v0 ? b[3] : b[2], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" "pr103215" { xfail *-*-* } } */
struct A { char a[5], b[5]; };
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2021-12-09 19:51 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-09 19:51 [gcc r12-5871] Extend the offset and size of merged object references [PR103215] Martin Sebor
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).