aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.dg
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2021-08-24 10:49:11 -0600
committerMartin Sebor <msebor@redhat.com>2021-08-24 10:49:11 -0600
commit820f0940d7ace1306430a9dcf1bd9577508a7a7e (patch)
treeb9517cd7a654bf06337532a5395539c4eaa6c55e /gcc/testsuite/gcc.dg
parent6d692ef43b2b3368c92c3fb757c7884fc94ee627 (diff)
downloadgcc-820f0940d7ace1306430a9dcf1bd9577508a7a7e.zip
gcc-820f0940d7ace1306430a9dcf1bd9577508a7a7e.tar.gz
gcc-820f0940d7ace1306430a9dcf1bd9577508a7a7e.tar.bz2
Reset PHI base0 flag if it's clear in any argument [PR101977, ...]
Resolves: PR middle-end/101600 - Spurious -Warray-bounds downcasting a polymorphic pointer PR middle-end/101977 - bogus -Warray-bounds on a negative index into a parameter in conditional with null gcc/ChangeLog: PR middle-end/101600 PR middle-end/101977 * gimple-ssa-warn-access.cc (maybe_warn_for_bound): Tighten up the phrasing of a warning. (check_access): Use the remaining size after subtracting any offset rather than the whole object size. * pointer-query.cc (access_ref::get_ref): Clear BASE0 flag if it's clear for any nonnull PHI argument. (compute_objsize): Clear argument. gcc/testsuite/ChangeLog: PR middle-end/101600 PR middle-end/101977 * g++.dg/pr100574.C: Prune out valid warning. * gcc.dg/pr20126.c: Same. * gcc.dg/Wstringop-overread.c: Adjust text of expected warnings. Add new instances. * gcc.dg/warn-strnlen-no-nul.c: Same. * g++.dg/warn/Warray-bounds-26.C: New test. * gcc.dg/Warray-bounds-88.c: New test.
Diffstat (limited to 'gcc/testsuite/gcc.dg')
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-88.c134
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overread.c32
-rw-r--r--gcc/testsuite/gcc.dg/pr20126.c6
-rw-r--r--gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c39
4 files changed, 177 insertions, 34 deletions
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-88.c b/gcc/testsuite/gcc.dg/Warray-bounds-88.c
new file mode 100644
index 0000000..8cee8d2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-88.c
@@ -0,0 +1,134 @@
+/* PR middle-end/101977 - bogus -Warray-bounds on a negative index into
+ a parameter in conditional with null
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+struct A { int i; };
+struct B { struct A a1; struct A a2; };
+
+
+void nowarn_p_0_0 (struct A *p, int i)
+{
+ struct A *q = i < 0 ? p : 0 < i ? (struct A*)0 : 0;
+ struct B *r = (struct B*)((char *)q - __builtin_offsetof (struct B, a2));
+ r->a1.i = 0;
+}
+
+void nowarn_0_p_0 (struct A *p, int i)
+{
+ struct A *q = i < 0 ? 0 : 0 < i ? p : 0;
+ struct B *r = (struct B*)((char *)q - __builtin_offsetof (struct B, a2));
+ r->a1.i = 0; // { dg-bogus "-Warray-bounds" }
+}
+
+void nowarn_0_0_p (struct A *p, int i)
+{
+ struct A *q = i < 0 ? 0 : 0 < i ? 0 : p;
+ struct B *r = (struct B*)((char *)q - __builtin_offsetof (struct B, a2));
+ r->a1.i = 0; // { dg-bogus "-Warray-bounds" }
+}
+
+
+void nowarn_p_q_0 (struct A *p, struct A *q, int i)
+{
+ struct A *r = i < 0 ? p : 0 < i ? q : 0;
+ struct B *s = (struct B*)((char *)r - __builtin_offsetof (struct B, a2));
+ s->a1.i = 0; // { dg-bogus "-Warray-bounds" }
+}
+
+void nowarn_p_0_q (struct A *p, struct A *q, int i)
+{
+ struct A *r = i < 0 ? p : 0 < i ? 0 : q;
+ struct B *s = (struct B*)((char *)r - __builtin_offsetof (struct B, a2));
+ s->a1.i = 0; // { dg-bogus "-Warray-bounds" }
+}
+
+void nowarn_0_p_q (struct A *p, struct A *q, int i)
+{
+ struct A *r = i < 0 ? 0 : 0 < i ? p : q;
+ struct B *s = (struct B*)((char *)r - __builtin_offsetof (struct B, a2));
+ s->a1.i = 0;
+}
+
+
+void nowarn_p_q_r (struct A *p, struct A *q, struct A *r, int i)
+{
+ struct A *s = i < 0 ? p : 0 < i ? q : r;
+ struct B *t = (struct B*)((char *)s - __builtin_offsetof (struct B, a2));
+ t->a1.i = 0;
+}
+
+
+extern struct B b1, b2, b3;
+
+void nowarn_p_b1_0 (struct A *p, int i)
+{
+ struct A *r = i < 0 ? p : 0 < i ? &b1.a2 : 0;
+ struct B *s = (struct B*)((char *)r - __builtin_offsetof (struct B, a2));
+ s->a1.i = 0; // { dg-bogus "-Warray-bounds" }
+}
+
+void nowarn_p_0_b1 (struct A *p, int i)
+{
+ struct A *r = i < 0 ? p : 0 < i ? 0 : &b1.a2;
+ struct B *s = (struct B*)((char *)r - __builtin_offsetof (struct B, a2));
+ s->a1.i = 0; // { dg-bogus "-Warray-bounds" }
+}
+
+void nowarn_0_p_b1 (struct A *p, int i)
+{
+ struct A *r = i < 0 ? 0 : 0 < i ? p : &b1.a2;
+ struct B *s = (struct B*)((char *)r - __builtin_offsetof (struct B, a2));
+ s->a1.i = 0;
+}
+
+
+void nowarn_p_b1_b2 (struct A *p, int i)
+{
+ struct A *s = i < 0 ? p : 0 < i ? &b1.a2 : &b2.a2;
+ struct B *t = (struct B*)((char *)s - __builtin_offsetof (struct B, a2));
+ t->a1.i = 0;
+}
+
+void nowarn_b1_p_b2 (struct A *p, int i)
+{
+ struct A *s = i < 0 ? &b1.a2 : 0 < i ? p : &b2.a2;
+ struct B *t = (struct B*)((char *)s - __builtin_offsetof (struct B, a2));
+ t->a1.i = 0;
+}
+
+void nowarn_b1_b2_p (struct A *p, int i)
+{
+ struct A *s = i < 0 ? &b1.a2 : 0 < i ? &b2.a2 : p;
+ struct B *t = (struct B*)((char *)s - __builtin_offsetof (struct B, a2));
+ t->a1.i = 0;
+}
+
+void nowarn_b1_b2_b3 (struct A *p, int i)
+{
+ struct A *s = i < 0 ? &b1.a2 : 0 < i ? &b2.a2 : &b3.a2;
+ struct B *t = (struct B*)((char *)s - __builtin_offsetof (struct B, a2));
+ t->a1.i = 0;
+}
+
+
+void nowarn_0_b1_b2 (int i)
+{
+ struct A *s = i < 0 ? 0 : 0 < i ? &b1.a2 : &b2.a2;
+ struct B *t = (struct B*)((char *)s - __builtin_offsetof (struct B, a2));
+ t->a1.i = 0;
+}
+
+void warn_b1_0_b2 (int i)
+{
+ struct A *s = i < 0 ? &b1.a2 : 0 < i ? 0 : &b2.a2;
+ struct B *t = (struct B*)((char *)s - __builtin_offsetof (struct B, a2));
+ t->a1.i = 0;
+}
+
+void warn_b1_b2_0 (int i)
+{
+ struct A *s = i < 0 ? &b1.a2 : 0 < i ? &b2.a2 : 0;
+ struct B *t = (struct B*)((char *)s - __builtin_offsetof (struct B, a2));
+ t->a1.i = 0;
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overread.c b/gcc/testsuite/gcc.dg/Wstringop-overread.c
index 0343e43..7db7402 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overread.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overread.c
@@ -317,9 +317,9 @@ void test_strnlen_array (int i, int i0, unsigned n)
T (strnlen (a1, n));
T (strnlen (a1 + 1, 0));
- T (strnlen (a1 + 1, 1)); // { dg-warning "'strnlen' reading 1 byte from a region of size 0" }
+ T (strnlen (a1 + 1, 1)); // { dg-warning "'strnlen' specified bound 1 exceeds source size 0" }
T (strnlen (a1 + 1, i0));
- T (strnlen (a1 + 1, i0 + 1)); // { dg-warning "'strnlen' reading between 1 and \[0-9\]+ bytes from a region of size 0" }
+ T (strnlen (a1 + 1, i0 + 1)); // { dg-warning "'strnlen' specified bound \\\[1, \\d+] exceeds source size 0" }
T (strnlen (a1 + 1, n));
T (strnlen (a1 + i, 0));
T (strnlen (a1 + i, 1));
@@ -335,7 +335,7 @@ void test_strnlen_array (int i, int i0, unsigned n)
T (strnlen (a1 + i0, 2)); // { dg-warning "'strnlen' specified bound 2 exceeds source size 1" }
T (strnlen (a1 + i0, n));
T (strnlen (a1 + i0 + 1, 0));
- T (strnlen (a1 + i0 + 1, 1)); // { dg-warning "'strnlen' reading 1 byte from a region of size 0" }
+ T (strnlen (a1 + i0 + 1, 1)); // { dg-warning "'strnlen' specified bound 1 exceeds source size 0" }
T (strnlen (a1 + i0 + 1, n));
T (strnlen (a2, 0));
@@ -344,10 +344,10 @@ void test_strnlen_array (int i, int i0, unsigned n)
T (strnlen (a2, n));
T (strnlen (a2 + 1, 0));
T (strnlen (a2 + 1, 1));
- T (strnlen (a2 + 1, 2)); // { dg-warning "'strnlen' specified bound 2 exceeds source size 1" "pr87492" { xfail *-*-* } }
+ T (strnlen (a2 + 1, 2)); // { dg-warning "'strnlen' specified bound 2 exceeds source size 1" "pr87492" }
T (strnlen (a2 + 1, n));
T (strnlen (a2 + 2, 0));
- T (strnlen (a2 + 2, 1)); // { dg-warning "'strnlen' reading 1 byte from a region of size 0" }
+ T (strnlen (a2 + 2, 1)); // { dg-warning "'strnlen' specified bound 1 exceeds source size 0" }
T (strnlen (a2 + 2, n));
T (strnlen (a2 + i, 0));
T (strnlen (a2 + i, 1));
@@ -365,13 +365,13 @@ void test_strnlen_array (int i, int i0, unsigned n)
T (strnlen (a2 + i0 + 1, 0));
T (strnlen (a2 + i0 + 1, 1));
- T (strnlen (a2 + i0 + 1, 2));
+ T (strnlen (a2 + i0 + 1, 2)); // { dg-warning "'strnlen' specified bound 2 exceeds source size 1" }
T (strnlen (a2 + i0 + 1, n));
T (strnlen (a2 + i0 + 2, 0));
- T (strnlen (a2 + i0 + 2, 1)); // { dg-warning "'strnlen' reading 1 byte from a region of size 0" }
+ T (strnlen (a2 + i0 + 2, 1)); // { dg-warning "'strnlen' specified bound 1 exceeds source size 0" }
T (strnlen (a2 + i0 + 2, i0));
- T (strnlen (a2 + i0 + 2, i0 + 1)); // { dg-warning "'strnlen' reading between 1 and \[0-9\]+ bytes from a region of size 0" }
+ T (strnlen (a2 + i0 + 2, i0 + 1)); // { dg-warning "'strnlen' specified bound \\\[1, \\d+] exceeds source size 0" }
T (strnlen (a2 + i0 + 2, n));
}
@@ -512,9 +512,9 @@ void test_strndup_array (int i, int i0, unsigned n)
T (strndup (a1, 2)); // { dg-warning "'strndup' specified bound 2 exceeds source size 1" }
T (strndup (a1, n));
T (strndup (a1 + 1, 0));
- T (strndup (a1 + 1, 1)); // { dg-warning "'strndup' reading 1 byte from a region of size 0" }
+ T (strndup (a1 + 1, 1)); // { dg-warning "'strndup' specified bound 1 exceeds source size 0" }
T (strndup (a1 + 1, i0));
- T (strndup (a1 + 1, i0 + 1)); // { dg-warning "'strndup' reading between 1 and \[0-9\]+ bytes from a region of size 0" }
+ T (strndup (a1 + 1, i0 + 1)); // { dg-warning "'strndup' specified bound \\\[1, \\d+] exceeds source size 0" }
T (strndup (a1 + 1, n));
T (strndup (a1 + i, 0));
T (strndup (a1 + i, 1));
@@ -529,7 +529,7 @@ void test_strndup_array (int i, int i0, unsigned n)
T (strndup (a1 + i0, 1));
T (strndup (a1 + i0, n));
T (strndup (a1 + i0 + 1, 0));
- T (strndup (a1 + i0 + 1, 1)); // { dg-warning "'strndup' reading 1 byte from a region of size 0" }
+ T (strndup (a1 + i0 + 1, 1)); // { dg-warning "'strndup' specified bound 1 exceeds source size 0" }
T (strndup (a1 + i0 + 1, n));
T (strndup (a2, 0));
@@ -538,10 +538,10 @@ void test_strndup_array (int i, int i0, unsigned n)
T (strndup (a2, n));
T (strndup (a2 + 1, 0));
T (strndup (a2 + 1, 1));
- T (strndup (a2 + 1, 2));
+ T (strndup (a2 + 1, 2)); // { dg-warning "'strndup' specified bound 2 exceeds source size 1" }
T (strndup (a2 + 1, n));
T (strndup (a2 + 2, 0));
- T (strndup (a2 + 2, 1)); // { dg-warning "'strndup' reading 1 byte from a region of size 0" }
+ T (strndup (a2 + 2, 1)); // { dg-warning "'strndup' specified bound 1 exceeds source size 0" }
T (strndup (a2 + 2, n));
T (strndup (a2 + i, 0));
T (strndup (a2 + i, 1));
@@ -559,13 +559,13 @@ void test_strndup_array (int i, int i0, unsigned n)
T (strndup (a2 + i0 + 1, 0));
T (strndup (a2 + i0 + 1, 1));
- T (strndup (a2 + i0 + 1, 2));
+ T (strndup (a2 + i0 + 1, 2)); // { dg-warning "'strndup' specified bound 2 exceeds source size 1" }
T (strndup (a2 + i0 + 1, n));
T (strndup (a2 + i0 + 2, 0));
- T (strndup (a2 + i0 + 2, 1)); // { dg-warning "'strndup' reading 1 byte from a region of size 0" }
+ T (strndup (a2 + i0 + 2, 1)); // { dg-warning "'strndup' specified bound 1 exceeds source size 0" }
T (strndup (a2 + i0 + 2, i0));
- T (strndup (a2 + i0 + 2, i0 + 1)); // { dg-warning "'strndup' reading between 1 and \[0-9\]+ bytes from a region of size 0" }
+ T (strndup (a2 + i0 + 2, i0 + 1)); // { dg-warning "'strndup' specified bound \\\[1, \\d+] exceeds source size 0" }
T (strndup (a2 + i0 + 2, n));
}
diff --git a/gcc/testsuite/gcc.dg/pr20126.c b/gcc/testsuite/gcc.dg/pr20126.c
index a421ce1..10aeec7 100644
--- a/gcc/testsuite/gcc.dg/pr20126.c
+++ b/gcc/testsuite/gcc.dg/pr20126.c
@@ -34,6 +34,10 @@ foo (S *x, S *y)
while (e <= g)
{
const char *t = e + 1;
+ /* The pointer E below increases but the bound H stays constant,
+ letting the latter exceed the size remaining in the argument
+ pointed to by the formed, which might be detected by
+ -Wstringop-overread. */
if (__builtin_memcmp (e, f, h) == 0)
return 1;
e = t;
@@ -48,3 +52,5 @@ main (void)
abort ();
return 0;
}
+
+/* { dg-prune-output "-Wstringop-overread" } */
diff --git a/gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c b/gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c
index 2afd2b5..846e930 100644
--- a/gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c
+++ b/gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c
@@ -143,14 +143,17 @@ T (v0 ? b[1] : "", bsz);
T (v0 ? b[2] : "", bsz);
T (v0 ? b[3] : "", bsz);
-T (v0 ? "" : b[0], bsz + 1); /* { dg-warning "bound 6 may exceed source size 5" } */
-T (v0 ? "" : b[1], bsz + 1);
-T (v0 ? "" : b[2], bsz + 1);
-T (v0 ? "" : b[3], bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */
-T (v0 ? b[0] : "", bsz + 1); /* { dg-warning "bound 6 may exceed source size 5" } */
-T (v0 ? b[1] : "", bsz + 1);
-T (v0 ? b[2] : "", bsz + 1);
-T (v0 ? b[3] : "", bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */
+/* 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. */
+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[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[i0], bsz);
T (v0 ? "" : b[i1], bsz);
@@ -164,11 +167,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 "unterminated" "pr86937" { xfail *-*-* } } */
+T (v0 ? "" : b[i3], bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" "pr86937" } */
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 "unterminated" "pr86937" { xfail *-*-* } } */
+T (v0 ? b[i3] : "", bsz + 1); /* { dg-warning "bound 6 exceeds source size 5" "pr86937" } */
T (v0 ? "1234" : b[3], bsz);
T (v0 ? "1234" : b[i3], bsz);
@@ -180,15 +183,15 @@ 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 "unterminated" "pr86937" { xfail *-*-* } } */
-T (v0 ? "1234" : b[i3], bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */
-T (v0 ? b[3] : "1234", bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */
-T (v0 ? b[i3] : "1234", bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */
+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 may exceed source size 5" "pr86937" { xfail *-*-*} } */
-T (v0 ? b[0] : b[2], bsz + 1); /* { dg-warning "bound 6 may exceed source size 5" "pr86937" } */
-T (v0 ? b[2] : b[3], bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */
-T (v0 ? b[3] : b[2], bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */
+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" } */
struct A { char a[5], b[5]; };