blob: 70f6a432b978be8c62ad6b17a1594e0f182b91e4 [file] [log] [blame]
/* PR tree-optimization/86552 - missing warning for reading past the end
of non-string arrays
{ dg-do compile }
{ dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */
typedef __SIZE_TYPE__ size_t;
extern size_t strnlen (const char*, size_t);
const char a[5] = "12345"; /* { dg-message "declared here" } */
enum { asz = sizeof a };
int v0 = 0;
int v1 = 1;
void sink (int, ...);
#define CONCAT(a, b) a ## b
#define CAT(a, b) CONCAT(a, b)
#define T(str, n) \
__attribute__ ((noipa)) \
void CAT (test_, __LINE__) (void) { \
int i0 = 0, i1 = i0 + 1, i2 = i1 + 1, i3 = i2 + 1; \
sink (strnlen (str, n), i0, i1, i2, i3); \
} typedef void dummy_type
T (a, asz);
T (a, asz - 1);
T (a, asz - 2);
T (a, asz - 5);
T (&a[0], asz);
T (&a[0] + 1, asz); /* { dg-warning "specified bound 5 exceeds the size 4 of unterminated array" } */
T (&a[1], asz); /* { dg-warning "specified bound 5 exceeds the size 4 of unterminated array" } */
T (&a[1], asz - 1);
T (&a[v0], asz); /* { dg-warning "specified bound 5 may exceed the size of at most 5 of unterminated array" } */
T (&a[v0] + 1, asz); /* { dg-warning "specified bound 5 may exceed the size of at most 5 of unterminated array" } */
T (a, asz + 1); /* { dg-warning "specified bound 6 exceeds the size 5 of unterminated array" } */
T (&a[0], asz + 1); /* { dg-warning "unterminated" } */
T (&a[0] + 1, asz - 1);
T (&a[0] + 1, asz + 1); /* { dg-warning "unterminated" } */
T (&a[1], asz + 1); /* { dg-warning "unterminated" } */
T (&a[v0], asz + 1); /* { dg-warning "unterminated" } */
T (&a[v0] + 1, asz + 1); /* { dg-warning "unterminated" } */
const char b[][5] = { /* { dg-message "declared here" } */
"12", "123", "1234", "54321"
};
enum { bsz = sizeof b[0] };
T (b[0], bsz);
T (b[1], bsz);
T (b[2], bsz);
T (b[3], bsz);
T (b[0], bsz - 1);
T (b[1], bsz - 1);
T (b[2], bsz - 1);
T (b[3], bsz - 1);
T (b[0], bsz + 1);
T (b[1], bsz + 1);
T (b[2], bsz + 1);
T (b[3], bsz + 1); /* { dg-warning "unterminated" } */
T (b[i0], bsz);
T (b[i1], bsz);
T (b[i2], bsz);
T (b[i3], bsz);
T (b[i0], bsz + 1);
T (b[i1], bsz + 1);
T (b[i2], bsz + 1);
T (b[i3], bsz + 1); /* { dg-warning "unterminated" } */
T (b[v0], bsz);
T (b[v0], bsz + 1);
T (&b[i2][i1], bsz);
T (&b[i2][i1] + i1, bsz);
T (&b[i2][v0], bsz);
T (&b[i2][i1] + v0, bsz);
T (&b[i2][i1], bsz + 1);
T (&b[i2][i1] + i1, bsz + 1);
T (&b[i2][v0], bsz + 1);
T (&b[i2][i1] + v0, bsz + 1);
T (&b[2][1], bsz);
T (&b[2][1] + i1, bsz);
T (&b[2][i0], bsz);
T (&b[2][1] + i0, bsz);
T (&b[2][1] + v0, bsz);
T (&b[2][v0], bsz);
T (&b[2][1], bsz + 1);
T (&b[2][1] + i1, bsz + 1);
T (&b[2][i0], bsz + 1);
T (&b[2][1] + i0, bsz + 1);
T (&b[2][1] + v0, bsz + 1);
T (&b[2][v0], bsz + 1);
T (&b[3][1], bsz); /* { dg-warning "unterminated" } */
T (&b[3][1], bsz - 1);
T (&b[3][1] + 1, bsz); /* { dg-warning "unterminated" } */
T (&b[3][1] + 1, bsz - 1); /* { dg-warning "unterminated" } */
T (&b[3][1] + 1, bsz - 2);
T (&b[3][1] + i1, bsz); /* { dg-warning "unterminated" } */
T (&b[3][1] + i1, bsz - i1); /* { dg-warning "unterminated" } */
T (&b[3][1] + i1, bsz - i2);
T (&b[3][v0], bsz);
T (&b[3][1] + v0, bsz); /* { dg-warning "specified bound 5 exceeds the size of at most 4 of unterminated array" } */
T (&b[3][v0] + v1, bsz); /* { dg-warning "specified bound 5 may exceed the size of at most 4 of unterminated array" "pr?????" { xfail *-*-* } } */
T (&b[3][1], bsz + 1); /* { dg-warning "unterminated" } */
T (&b[3][1] + 1, bsz + 1); /* { dg-warning "unterminated" } */
T (&b[3][1] + i1, bsz + 1); /* { dg-warning "unterminated" } */
T (&b[3][v0], bsz + 1); /* { dg-warning "unterminated" "pr86936" { xfail *-*-* } } */
T (&b[3][1] + v0, bsz + 1); /* { dg-warning "unterminated" } */
T (&b[3][v0] + v1, bsz + 1); /* { dg-warning "unterminated" "pr86936" { xfail *-*-* } } */
T (&b[i3][i1], bsz); /* { dg-warning "unterminated" } */
T (&b[i3][i1] + 1, bsz); /* { dg-warning "unterminated" } */
T (&b[i3][i1] + i1, bsz); /* { dg-warning "specified bound 5 exceeds the size 3 of unterminated array" } */
T (&b[i3][v0], bsz);
T (&b[i3][i1] + v0, bsz); /* { dg-warning "specified bound 5 exceeds the size of at most 4 of unterminated array" } */
T (&b[i3][v0] + v1, bsz);
T (&b[i3][i1], bsz + 1); /* { dg-warning "unterminated" } */
T (&b[i3][i1] + 1, bsz + 1); /* { dg-warning "unterminated" } */
T (&b[i3][i1] + i1, bsz + 1); /* { dg-warning "unterminated" } */
T (&b[i3][v0], bsz + 1); /* { dg-warning "unterminated" "pr86919" { xfail *-*-* } } */
T (&b[i3][i1] + v0, bsz + 1); /* { dg-warning "unterminated" } */
T (&b[i3][v0] + v1, bsz + 1); /* { dg-warning "unterminated" "pr86919" { xfail *-*-* } } */
T (v0 ? "" : b[0], bsz);
T (v0 ? "" : b[1], bsz);
T (v0 ? "" : b[2], bsz);
T (v0 ? "" : b[3], bsz);
T (v0 ? b[0] : "", bsz);
T (v0 ? b[1] : "", bsz);
T (v0 ? b[2] : "", bsz);
T (v0 ? b[3] : "", bsz);
/* 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);
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);
T (v0 ? b[2] : "", bsz + 1);
T (v0 ? b[3] : "", bsz + 1);
T (v0 ? "" : b[i0], bsz);
T (v0 ? "" : b[i1], bsz);
T (v0 ? "" : b[i2], bsz);
T (v0 ? "" : b[i3], bsz);
T (v0 ? b[i0] : "", bsz);
T (v0 ? b[i1] : "", bsz);
T (v0 ? b[i2] : "", bsz);
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);
T (v0 ? b[i0] : "", bsz + 1);
T (v0 ? b[i1] : "", bsz + 1);
T (v0 ? b[i2] : "", bsz + 1);
T (v0 ? b[i3] : "", bsz + 1);
T (v0 ? "1234" : b[3], bsz);
T (v0 ? "1234" : b[i3], bsz);
T (v0 ? b[3] : "1234", bsz);
T (v0 ? b[i3] : "1234", bsz);
T (v0 ? a : b[3], bsz);
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);
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]; };
const struct A s = { "1234", "12345" };
T (s.a, asz);
T (&s.a[0], asz);
T (&s.a[0] + 1, asz);
T (&s.a[0] + v0, asz);
T (&s.a[1], asz);
T (&s.a[1] + 1, asz);
T (&s.a[1] + v0, asz);
T (&s.a[i0], asz);
T (&s.a[i0] + i1, asz);
T (&s.a[i0] + v0, asz);
T (&s.a[i1], asz);
T (&s.a[i1] + i1, asz);
T (&s.a[i1] + v0, asz);
T (s.a, asz + 1);
T (&s.a[0], asz + 1);
T (&s.a[0] + 1, asz + 1);
T (&s.a[0] + v0, asz + 1); /* { dg-warning "specified bound 6 exceeds source size 5 " } */
T (&s.a[1], asz + 1);
T (&s.a[1] + 1, asz + 1);
T (&s.a[1] + v0, asz + 1); /* { dg-bogus "specified bound 6 exceeds source size 5" "pr95794" { xfail *-*-* } } */
T (&s.a[i0], asz + 1);
T (&s.a[i0] + i1, asz + 1);
T (&s.a[i0] + v0, asz + 1);
T (&s.a[i1], asz + 1);
T (&s.a[i1] + i1, asz + 1);
T (&s.a[i1] + v0, asz + 1);
T (s.b, bsz);
T (&s.b[0], bsz);
T (&s.b[0] + 1, bsz); /* { dg-warning "unterminated" } */
T (&s.b[0] + v0, bsz); /* { dg-warning "unterminated" } */
T (&s.b[1], bsz); /* { dg-warning "unterminated" } */
T (&s.b[1] + 1, bsz); /* { dg-warning "unterminated" } */
T (&s.b[1] + v0, bsz); /* { dg-warning "unterminated" } */
T (&s.b[i0], bsz);
T (&s.b[i0] + i1, bsz); /* { dg-warning "unterminated" } */
T (&s.b[i0] + v0, bsz); /* { dg-warning "unterminated" } */
T (&s.b[i1], bsz); /* { dg-warning "unterminated" } */
T (&s.b[i1] + i1, bsz); /* { dg-warning "unterminated" } */
T (&s.b[i1] + v0, bsz); /* { dg-warning "unterminated" } */
T (s.b, bsz + 1); /* { dg-warning "unterminated" } */
T (&s.b[0], bsz + 1); /* { dg-warning "unterminated" } */
T (&s.b[0] + 1, bsz + 1); /* { dg-warning "unterminated" } */
T (&s.b[0] + v0, bsz + 1); /* { dg-warning "unterminated" } */
T (&s.b[1], bsz + 1); /* { dg-warning "unterminated" } */
T (&s.b[1] + 1, bsz + 1); /* { dg-warning "unterminated" } */
T (&s.b[1] + v0, bsz + 1); /* { dg-warning "unterminated" } */
T (&s.b[i0], bsz + 1); /* { dg-warning "unterminated" } */
T (&s.b[i0] + i1, bsz + 1); /* { dg-warning "unterminated" } */
T (&s.b[i0] + v0, bsz + 1); /* { dg-warning "unterminated" } */
T (&s.b[i1], bsz + 1); /* { dg-warning "unterminated" } */
T (&s.b[i1] + i1, bsz + 1); /* { dg-warning "unterminated" } */
T (&s.b[i1] + v0, bsz + 1); /* { dg-warning "unterminated" } */
struct B { struct A a[2]; };
const struct B ba[] = {
{ { { "123", "12345" }, { "12345", "123" } } },
{ { { "12345", "123" }, { "123", "12345" } } },
{ { { "1", "12" }, { "123", "1234" } } },
{ { { "123", "1234" }, { "12345", "12" } } }
};
T (ba[0].a[0].a, asz + 1);
T (&ba[0].a[0].a[0], asz + 1);
T (&ba[0].a[0].a[0] + 1, asz + 1);
T (&ba[0].a[0].a[0] + v0, asz + 1); /* { dg-bogus "specified bound 6 exceeds source size 5" pr95794" { xfail *-*-* } } */
T (&ba[0].a[0].a[1], asz + 1);
T (&ba[0].a[0].a[1] + 1, asz + 1);
T (&ba[0].a[0].a[1] + v0, asz + 1); /* { dg-bogus "specified bound 6 exceeds source size 5" pr95794" { xfail *-*-* } } */
T (ba[0].a[0].b, bsz);
T (&ba[0].a[0].b[0], bsz);
T (&ba[0].a[0].b[0] + 1, bsz); /* { dg-warning "unterminated" } */
T (&ba[0].a[0].b[0] + 1, bsz - 1);
T (&ba[0].a[0].b[0] + v0, bsz); /* { dg-warning "unterminated" } */
T (&ba[0].a[0].b[1], bsz); /* { dg-warning "unterminated" } */
T (&ba[0].a[0].b[1], bsz - 1);
T (&ba[0].a[0].b[1] + 1, bsz - 1); /* { dg-warning "unterminated" } */
T (&ba[0].a[0].b[1] + 1, bsz - 2);
T (&ba[0].a[0].b[1] + 1, bsz); /* { dg-warning "unterminated" } */
T (&ba[0].a[0].b[1] + v0, bsz); /* { dg-warning "unterminated" } */
T (ba[0].a[0].b, bsz + 1); /* { dg-warning "unterminated" } */
T (&ba[0].a[0].b[0], bsz + 1); /* { dg-warning "unterminated" } */
T (&ba[0].a[0].b[0] + 1, bsz + 1); /* { dg-warning "unterminated" } */
T (&ba[0].a[0].b[0] + v0, bsz + 1); /* { dg-warning "unterminated" } */
T (&ba[0].a[0].b[1], bsz + 1); /* { dg-warning "unterminated" } */
T (&ba[0].a[0].b[1] + 1, bsz + 1); /* { dg-warning "unterminated" } */
T (&ba[0].a[0].b[1] + v0, bsz + 1); /* { dg-warning "unterminated" } */
T (ba[0].a[1].a, asz + 1); /* { dg-warning "unterminated" } */
T (&ba[0].a[1].a[0], asz + 1); /* { dg-warning "unterminated" } */
T (&ba[0].a[1].a[0] + 1, asz + 1); /* { dg-warning "unterminated" } */
T (&ba[0].a[1].a[0] + v0, asz + 1); /* { dg-warning "unterminated" } */
T (&ba[0].a[1].a[1], asz + 1); /* { dg-warning "unterminated" } */
T (&ba[0].a[1].a[1] + 1, asz + 1); /* { dg-warning "unterminated" } */
T (&ba[0].a[1].a[1] + v0, asz + 1); /* { dg-warning "unterminated" } */
T (ba[0].a[1].b, bsz + 1);
T (&ba[0].a[1].b[0], bsz + 1);
T (&ba[0].a[1].b[0] + 1, bsz + 1);
T (&ba[0].a[1].b[0] + v0, bsz + 1); /* { dg-bogus "specified bound 6 exceeds source size 5" pr95794" { xfail *-*-* } } */
T (&ba[0].a[1].b[1], bsz + 1);
T (&ba[0].a[1].b[1] + 1, bsz + 1);
T (&ba[0].a[1].b[1] + v0, bsz + 1); /* { dg-bogus "specified bound 6 exceeds source size 5" pr95794" { xfail *-*-* } } */
T (ba[1].a[0].a, asz);
T (&ba[1].a[0].a[0], asz);
T (&ba[1].a[0].a[0] + 1, asz); /* { dg-warning "unterminated" } */
T (&ba[1].a[0].a[0] + v0, asz); /* { dg-warning "unterminated" } */
T (&ba[1].a[0].a[1], asz); /* { dg-warning "unterminated" } */
T (&ba[1].a[0].a[1] + 1, asz); /* { dg-warning "unterminated" } */
T (&ba[1].a[0].a[1] + v0, asz); /* { dg-warning "unterminated" } */
T (ba[1].a[0].a, asz + 1); /* { dg-warning "unterminated" } */
T (&ba[1].a[0].a[0], asz + 1); /* { dg-warning "unterminated" } */
T (&ba[1].a[0].a[0] + 1, asz + 1); /* { dg-warning "unterminated" } */
T (&ba[1].a[0].a[0] + v0, asz + 1); /* { dg-warning "unterminated" } */
T (&ba[1].a[0].a[1], asz + 1); /* { dg-warning "unterminated" } */
T (&ba[1].a[0].a[1] + 1, asz + 1); /* { dg-warning "unterminated" } */
T (&ba[1].a[0].a[1] + v0, asz + 1); /* { dg-warning "unterminated" } */
T (ba[1].a[0].b, bsz);
T (&ba[1].a[0].b[0], bsz);
T (&ba[1].a[0].b[0] + 1, bsz);
T (&ba[1].a[0].b[0] + v0, bsz);
T (&ba[1].a[0].b[1], bsz);
T (&ba[1].a[0].b[1] + 1, bsz);
T (&ba[1].a[0].b[1] + v0, bsz);
T (ba[1].a[1].a, asz);
T (&ba[1].a[1].a[0], asz);
T (&ba[1].a[1].a[0] + 1, asz);
T (&ba[1].a[1].a[0] + v0, asz);
T (&ba[1].a[1].a[1], asz);
T (&ba[1].a[1].a[1] + 1, asz);
T (&ba[1].a[1].a[1] + v0, asz);
T (ba[1].a[1].b, bsz);
T (&ba[1].a[1].b[0], bsz);
T (&ba[1].a[1].b[0] + 1, bsz); /* { dg-warning "unterminated" } */
T (&ba[1].a[1].b[0] + 1, bsz - 1);
T (&ba[1].a[1].b[0] + v0, bsz); /* { dg-warning "unterminated" } */
T (&ba[1].a[1].b[1], bsz); /* { dg-warning "unterminated" } */
T (&ba[1].a[1].b[1], bsz - 1);
T (&ba[1].a[1].b[1] + 1, bsz); /* { dg-warning "unterminated" } */
T (&ba[1].a[1].b[1] + 1, bsz - 1); /* { dg-warning "unterminated" } */
T (&ba[1].a[1].b[1] + 1, bsz - 2);
T (&ba[1].a[1].b[1] + 1, bsz - i2);
T (&ba[1].a[1].b[1] + v0, bsz); /* { dg-warning "unterminated" } */
/* Prune out warnings with no location (pr?????).
{ dg-prune-output "cc1:" } */