diff options
author | Martin Sebor <msebor@redhat.com> | 2020-04-21 10:59:24 -0600 |
---|---|---|
committer | Martin Sebor <msebor@redhat.com> | 2020-04-21 11:11:06 -0600 |
commit | 3942060c4b3168307b9e2870d81e7ca15b49760a (patch) | |
tree | 63775e1c15a45fc845647576c47d8e22cd3a4620 /gcc/gimple-ssa-warn-restrict.c | |
parent | fb22faf48f6eb518932f24005f8606e5f19a7304 (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.c | 40 |
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; } |