The code that detects out-of-bounds pointers in calls to built-ins like memcpy with POINTER_PLUS_EXPR arguments tried a little too hard to detect out-of-bounds offsets and didn't handle anti-ranges correctly. I don't see how it could have ever worked and there were no tests for it in the test suite. PR 88273, however, has a test case that triggers the bug and causes a false positive. The attached patch removes the incorrect anti-range handling and replaces it with the varying fallback when no range info is available.
Removing my own buggy code seems like an obviously correct and safe solution so I committed it in r268048 after testing on x86_64-linux and verifying the test case with a powerpc-linux cross (with which the bug was first discovered). Since this regression affects both GCC 9 and 8 I will backport it to 8 as well. Martin
PR middle-end/88273 - [8/9 Regression] warning: 'memcpy' offset [-527, -529] is out of the bounds [0, 16] gcc/ChangeLog: PR middle-end/88273 * gimple-ssa-warn-restrict.c (builtin_memref::extend_offset_range): Handle anti-ranges the same as no range at all. gcc/testsuite/ChangeLog: PR middle-end/88273 * gcc.dg/Warray-bounds-38.c: New test. Index: gcc/gimple-ssa-warn-restrict.c =================================================================== --- gcc/gimple-ssa-warn-restrict.c (revision 268037) +++ gcc/gimple-ssa-warn-restrict.c (working copy) @@ -319,13 +319,9 @@ builtin_memref::extend_offset_range (tree offset) offrange[0] += offset_int::from (min, SIGNED); offrange[1] += offset_int::from (max, SIGNED); } - else if (rng == VR_ANTI_RANGE) - { - offrange[0] += offset_int::from (max + 1, SIGNED); - offrange[1] += offset_int::from (min - 1, SIGNED); - } else { + /* Handle an anti-range the same as no range at all. */ gimple *stmt = SSA_NAME_DEF_STMT (offset); tree type; if (is_gimple_assign (stmt) Index: gcc/testsuite/gcc.dg/Warray-bounds-38.c =================================================================== --- gcc/testsuite/gcc.dg/Warray-bounds-38.c (nonexistent) +++ gcc/testsuite/gcc.dg/Warray-bounds-38.c (working copy) @@ -0,0 +1,30 @@ +/* PR middle-end/88273 - bogus warning: 'memcpy' offset [-527, -529] + is out of the bounds [0, 16] + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +typedef __SIZE_TYPE__ size_t; + +void *q; + +size_t x, y; + +inline void f (char *p, int i, size_t j) +{ + size_t n = y ? y : j; + + p += x - i; + + __builtin_memcpy (q, p, n); /* { dg-bogus "bounds" } */ + + x = n; +} + +void g (void) +{ + struct { char a[16]; } s; + + f (q, 0, sizeof s); + + f (s.a, 33 * sizeof s, 1); +}