summaryrefslogtreecommitdiff
path: root/gcc/gimple-ssa-warn-restrict.c
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2020-04-21 10:59:24 -0600
committerMartin Sebor <msebor@redhat.com>2020-04-21 11:11:06 -0600
commit3942060c4b3168307b9e2870d81e7ca15b49760a (patch)
tree63775e1c15a45fc845647576c47d8e22cd3a4620 /gcc/gimple-ssa-warn-restrict.c
parentfb22faf48f6eb518932f24005f8606e5f19a7304 (diff)
PR middle-end/94647 - bogus -Warray-bounds on strncpy into a larger member array from a smaller array
gcc/ChangeLog: PR middle-end/94647 * gimple-ssa-warn-restrict.c (builtin_access::builtin_access): Correct the computation of the lower bound of the source access size. (builtin_access::generic_overlap): Remove a hack for setting ranges of overlap offsets. gcc/testsuite/ChangeLog: PR middle-end/94647 * c-c++-common/Warray-bounds-2.c: Adjust a test case and add a new one. * c-c++-common/Warray-bounds-3.c: Add tests for missing warnings. * c-c++-common/Wrestrict.c: Invert bounds in printed ranges. * gcc.dg/Warray-bounds-59.c: New test. * gcc.dg/Wrestrict-10.c: Add a missing warning. * gcc.dg/Wrestrict-5.c: Adjust text of expected warning. * gcc.dg/Wrestrict-6.c: Expect to see a range of overlap offsets.
Diffstat (limited to 'gcc/gimple-ssa-warn-restrict.c')
-rw-r--r--gcc/gimple-ssa-warn-restrict.c40
1 files changed, 9 insertions, 31 deletions
diff --git a/gcc/gimple-ssa-warn-restrict.c b/gcc/gimple-ssa-warn-restrict.c
index a6a96353a8c..19d2ec09aa5 100644
--- a/gcc/gimple-ssa-warn-restrict.c
+++ b/gcc/gimple-ssa-warn-restrict.c
@@ -831,8 +831,8 @@ builtin_access::builtin_access (gimple *call, builtin_memref &dst,
}
else if (srcref->sizrange[0] == 0 && srcref->sizrange[1] == maxobjsize)
{
- /* When the source size is unknown set it to the size of
- the destination. */
+ /* When the size of the source access is unknown set it to the size
+ of the destination first and adjust it later if necessary. */
srcref->sizrange[0] = dstref->sizrange[0];
srcref->sizrange[1] = dstref->sizrange[1];
@@ -842,15 +842,11 @@ builtin_access::builtin_access (gimple *call, builtin_memref &dst,
{
/* Read access by strncpy is constrained by the third
argument but except for a zero bound is at least one. */
- offset_int size = wi::umax (srcref->basesize, 1);
- offset_int bound = wi::umin (size, bounds[0]);
- if (bound < srcref->sizrange[0])
- srcref->sizrange[0] = bound;
- bound = wi::umin (srcref->basesize, bounds[1]);
+ srcref->sizrange[0] = bounds[1] > 0 ? 1 : 0;
+ offset_int bound = wi::umin (srcref->basesize, bounds[1]);
if (bound < srcref->sizrange[1])
srcref->sizrange[1] = bound;
}
-
/* For string functions, adjust the size range of the source
reference by the inverse boundaries of the offset (because
the higher the offset into the string the shorter its
@@ -859,7 +855,7 @@ builtin_access::builtin_access (gimple *call, builtin_memref &dst,
&& srcref->offrange[1] < srcref->sizrange[0])
srcref->sizrange[0] -= srcref->offrange[1];
else
- srcref->sizrange[0] = 0;
+ srcref->sizrange[0] = 1;
if (srcref->offrange[0] > 0)
{
@@ -1060,16 +1056,8 @@ builtin_access::generic_overlap ()
ovloff[0] = HOST_WIDE_INT_MAX;
ovloff[1] = HOST_WIDE_INT_MIN;
- /* Adjustment to the lower bound of the offset of the overlap to
- account for a subset of unbounded string calls where the size
- of the destination string depends on the length of the source
- which in turn depends on the offset into it. */
- bool sub1;
-
if (stxcpy_p)
{
- sub1 = acs.dstoff[0] <= acs.srcoff[0];
-
/* Iterate over the extreme locations (on the horizontal axis formed
by their offsets) and sizes of two regions and find their smallest
and largest overlap and the corresponding offsets. */
@@ -1102,11 +1090,9 @@ builtin_access::generic_overlap ()
}
else
{
- sub1 = !depends_p;
-
/* Iterate over the extreme locations (on the horizontal axis
- formed by their offsets) and sizes of two regions and find
- their smallest and largest overlap and the corresponding
+ formed by their offsets) and sizes of the two regions and
+ find their smallest and largest overlap and the corresponding
offsets. */
for (unsigned io = 0; io != 2; ++io)
@@ -1119,15 +1105,6 @@ builtin_access::generic_overlap ()
for (unsigned jo = 0; jo != 2; ++jo)
for (unsigned js = 0; js != 2; ++js)
{
- if (depends_p)
- {
- /* For st{p,r}ncpy the size of the source sequence
- depends on the offset into it. */
- if (js)
- break;
- js = !jo;
- }
-
const offset_int b[2] = {
acs.srcoff[jo], acs.srcoff[jo] + acs.srcsiz[js]
};
@@ -1154,8 +1131,9 @@ builtin_access::generic_overlap ()
ovlsiz[0] = siz[0].to_shwi ();
ovlsiz[1] = siz[1].to_shwi ();
+ /* Adjust the overlap offset range to reflect the overlap size range. */
if (ovlsiz[0] == 0 && ovlsiz[1] > 1)
- ovloff[0] = ovloff[1] + ovlsiz[1] - 1 - sub1;
+ ovloff[1] = ovloff[0] + ovlsiz[1] - 1;
return true;
}