public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/106757] New: Incorrect "writing 1 byte into a region of size 0" warning
@ 2022-08-26 18:32 jonathan.leffler at gmail dot com
  2022-08-26 18:37 ` [Bug tree-optimization/106757] [12/13 Regression] " pinskia at gcc dot gnu.org
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: jonathan.leffler at gmail dot com @ 2022-08-26 18:32 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106757

            Bug ID: 106757
           Summary: Incorrect "writing 1 byte into a region of size 0"
                    warning
           Product: gcc
           Version: 12.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jonathan.leffler at gmail dot com
  Target Milestone: ---

Created attachment 53515
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53515&action=edit
Source code (gcc-bug.c) for the repro

GCC 11.2.0 is happy with this code (and I believe it is correct).  Neither GCC
12.1.0 nor GCC 12.2.0 are happy with this code (and I believe this is a bug). 
There are no preprocessor directives in the source code.

$ /usr/gcc/v12.2.0/bin/gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/work1/gcc/v12.2.0/bin/../libexec/gcc/x86_64-pc-linux-gnu/12.2.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../gcc-12.2.0/configure --prefix=/usr/gcc/v12.2.0
CC=/usr/bin/gcc CXX=/usr/bin/g++
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 12.2.0 (GCC) 
$

Compilation:

$ /usr/gcc/v11.2.0/bin/gcc -c -std=c99 -O3 -Wall -Werror -pedantic -Wextra 
gcc-bug.c
$ /usr/gcc/v12.2.0/bin/gcc -c -std=c99 -O3 -Wall -Werror -pedantic -Wextra 
gcc-bug.c
gcc-bug.c: In function ‘pqr_scanner’:
gcc-bug.c:16:24: error: writing 1 byte into a region of size 0
[-Werror=stringop-overflow=]
   16 |             tmpchar[k] = mbs[k];
      |             ~~~~~~~~~~~^~~~~~~~
gcc-bug.c:14:14: note: at offset 4 into destination object ‘tmpchar’ of size 4
   14 |         char tmpchar[MBC_MAX];
      |              ^~~~~~~
gcc-bug.c:16:24: error: writing 1 byte into a region of size 0
[-Werror=stringop-overflow=]
   16 |             tmpchar[k] = mbs[k];
      |             ~~~~~~~~~~~^~~~~~~~
gcc-bug.c:14:14: note: at offset 5 into destination object ‘tmpchar’ of size 4
   14 |         char tmpchar[MBC_MAX];
      |              ^~~~~~~
cc1: all warnings being treated as errors
$

The -Wall, -Wextra, -pedantic options are not necessary to generate the
warning; the -Werror gives an error instead of a warning, of course.

$ cat gcc-bug.i
# 0 "gcc-bug.c"
# 0 "<built-in>"
# 0 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 0 "<command-line>" 2
# 1 "gcc-bug.c"
enum { MBC_MAX = 4 };

extern int pqr_scanner(char *mbs);
extern int pqr_mbc_len(char *mbs, int n);
extern void pqr_use_mbs(const char *mbs, int len);
extern char *pqr_mbs_nxt(char *mbs);

int
pqr_scanner(char *mbs)
{
    while (mbs != 0 && *mbs != '\0')
    {
        int len = pqr_mbc_len(mbs, MBC_MAX);
        char tmpchar[MBC_MAX];
        for (int k = 0; k < len; k++)
            tmpchar[k] = mbs[k];
        pqr_use_mbs(tmpchar, len);

        mbs = pqr_mbs_nxt(mbs);
    }

    return 0;
}
$

The source code contains a comment noting that if I replace `mbs =
pqr_nbs_nxt(mbs);` with `mbs += len;`, the bug does not reproduce.

In the original code (which was doing work with multi-byte characters and
strings), the analogue of pqr_mbc_len() returns either -1 or a value
1..MBC_MAX.    The code for the pqr_mbc_len() function was not part of the TU. 
There was a test for `if (len < 0) return -1;` after the call to pqr_mbc_len()
but it wasn't needed for the repro.

Just in case - GCC 11.2.0 specs and output from uname -a:

$ /usr/gcc/v11.2.0/bin/gcc -v
Using built-in specs.
COLLECT_GCC=/usr/gcc/v11.2.0/bin/gcc
COLLECT_LTO_WRAPPER=/work1/gcc/v11.2.0/bin/../libexec/gcc/x86_64-pc-linux-gnu/11.2.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../gcc-11.2.0/configure --prefix=/usr/gcc/v11.2.0
CC=/usr/bin/gcc CXX=/usr/bin/g++
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 11.2.0 (GCC)
$ uname -a
Linux njdc-ldev04 3.10.0-693.el7.x86_64 #1 SMP Thu Jul 6 19:56:57 EDT 2017
x86_64 x86_64 x86_64 GNU/Linux
$

The original function was 100 lines of code in a file of 2600 lines, including
20 headers directly.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug tree-optimization/106757] [12/13 Regression] Incorrect "writing 1 byte into a region of size 0" warning
  2022-08-26 18:32 [Bug c/106757] New: Incorrect "writing 1 byte into a region of size 0" warning jonathan.leffler at gmail dot com
@ 2022-08-26 18:37 ` pinskia at gcc dot gnu.org
  2022-08-26 19:21 ` [Bug tree-optimization/106757] [12/13 Regression] Incorrect "writing 1 byte into a region of size 0" on a vectorized loop msebor at gcc dot gnu.org
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-08-26 18:37 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106757

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Target Milestone|---                         |12.3
           See Also|                            |https://gcc.gnu.org/bugzill
                   |                            |a/show_bug.cgi?id=96447
            Summary|Incorrect "writing 1 byte   |[12/13 Regression]
                   |into a region of size 0"    |Incorrect "writing 1 byte
                   |warning                     |into a region of size 0"
                   |                            |warning

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug tree-optimization/106757] [12/13 Regression] Incorrect "writing 1 byte into a region of size 0" on a vectorized loop
  2022-08-26 18:32 [Bug c/106757] New: Incorrect "writing 1 byte into a region of size 0" warning jonathan.leffler at gmail dot com
  2022-08-26 18:37 ` [Bug tree-optimization/106757] [12/13 Regression] " pinskia at gcc dot gnu.org
@ 2022-08-26 19:21 ` msebor at gcc dot gnu.org
  2022-08-29  8:26 ` rguenth at gcc dot gnu.org
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: msebor at gcc dot gnu.org @ 2022-08-26 19:21 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106757

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|                            |2022-08-26
             Blocks|                            |88443
                 CC|                            |msebor at gcc dot gnu.org
     Ever confirmed|0                           |1
             Status|UNCONFIRMED                 |NEW
            Summary|[12/13 Regression]          |[12/13 Regression]
                   |Incorrect "writing 1 byte   |Incorrect "writing 1 byte
                   |into a region of size 0"    |into a region of size 0" on
                   |warning                     |a vectorized loop

--- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> ---
GCC unrolls the loop, and GCC 12 also vectorizes it.  The combination of the
two isolates stores from the loop that are out of bounds but that GCC cannot
prove cannot happen: it has no insight into what value pqr_mbc_len() might
return and if it's 5 or more the code would indeed write past the end.  The
warning just points it out.  To "fix" this the unroller could use the bounds of
the destination array to avoid emitting code for iterations of the loop that
end up accessing objects outside their bounds (there already is logic that does
that, controlled by the -faggressive-loop-optimizations option).  Until then,
if the function is guaranteed to return a value between 0 and 4 then adding the
following assertion both avoids the warning and improves the emitted code.

        if (len < 0 || MBC_MAX < len)
          __builtin_unreachable ();

The invalid stores can be seen in the IL output by the
-fdump-tree-strlen=/dev/stdout developer option:

  <bb 7> [local count: 76354976]:
  bnd.6_47 = _26 >> 2;
  vect__3.11_53 = MEM <vector(4) char> [(char *)mbs_22];
  MEM <vector(4) char> [(char *)&tmpchar] = vect__3.11_53;
  vectp_mbs.9_52 = mbs_22 + 4;
  niters_vector_mult_vf.7_48 = bnd.6_47 << 2;
  tmp.8_49 = (int) niters_vector_mult_vf.7_48;
  if (_26 == niters_vector_mult_vf.7_48)
    goto <bb 15>; [25.00%]
  else
    goto <bb 8>; [75.00%]

  <bb 8> [local count: 57266232]:
  _75 = (sizetype) tmp.8_49;
  _76 = vectp_mbs.9_52;
  _77 = MEM[(char *)vectp_mbs.9_52];
  tmpchar[tmp.8_49] = _77;   <<< -Wstringop-overflow
  k_79 = tmp.8_49 + 1;
  if (len_12 > 5)
    goto <bb 9>; [80.00%]
  else
    goto <bb 15>; [20.00%]

  <bb 9> [local count: 45812986]:
  _82 = 5;
  _83 = mbs_22 + 5;
  _84 = *_83;
  tmpchar[5] = _84;          <<< -Wstringop-overflow
  k_86 = tmp.8_49 + 2;
  if (len_12 > k_86)
    goto <bb 10>; [80.00%]
  else
    goto <bb 15>; [20.00%]


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88443
[Bug 88443] [meta-bug] bogus/missing -Wstringop-overflow warnings

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug tree-optimization/106757] [12/13 Regression] Incorrect "writing 1 byte into a region of size 0" on a vectorized loop
  2022-08-26 18:32 [Bug c/106757] New: Incorrect "writing 1 byte into a region of size 0" warning jonathan.leffler at gmail dot com
  2022-08-26 18:37 ` [Bug tree-optimization/106757] [12/13 Regression] " pinskia at gcc dot gnu.org
  2022-08-26 19:21 ` [Bug tree-optimization/106757] [12/13 Regression] Incorrect "writing 1 byte into a region of size 0" on a vectorized loop msebor at gcc dot gnu.org
@ 2022-08-29  8:26 ` rguenth at gcc dot gnu.org
  2022-10-03 23:12 ` bergner at gcc dot gnu.org
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: rguenth at gcc dot gnu.org @ 2022-08-29  8:26 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106757

--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
The unroller has code to put unreachable()s in paths like those but it's
imperfect.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug tree-optimization/106757] [12/13 Regression] Incorrect "writing 1 byte into a region of size 0" on a vectorized loop
  2022-08-26 18:32 [Bug c/106757] New: Incorrect "writing 1 byte into a region of size 0" warning jonathan.leffler at gmail dot com
                   ` (2 preceding siblings ...)
  2022-08-29  8:26 ` rguenth at gcc dot gnu.org
@ 2022-10-03 23:12 ` bergner at gcc dot gnu.org
  2022-10-19  7:05 ` rguenth at gcc dot gnu.org
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: bergner at gcc dot gnu.org @ 2022-10-03 23:12 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106757

Peter Bergner <bergner at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bergner at gcc dot gnu.org

--- Comment #3 from Peter Bergner <bergner at gcc dot gnu.org> ---
Is this the same bug, so just a simpler test case?

bergner@fowler:LTC193379$ cat bug.c
int len = 16;
extern char *src;
char dst[16];

void
foo (void)
{
#ifdef OK
  for (int i = 0; i < 16; i++)
#else
  for (int i = 0; i < len; i++)
#endif
    dst[i] = src[i];
}

bergner@fowler:LTC193379$
/home/bergner/gcc/build/gcc-fsf-mainline-ltc193379-debug/gcc/xgcc
-B/home/bergner/gcc/build/gcc-fsf-mainline-ltc193379-debug/gcc -S -O3 -DOK
-ftree-vectorize bug.c

bergner@fowler:LTC193379$
/home/bergner/gcc/build/gcc-fsf-mainline-ltc193379-debug/gcc/xgcc
-B/home/bergner/gcc/build/gcc-fsf-mainline-ltc193379-debug/gcc -S -O3 -UOK
-fno-tree-vectorize bug.c

bergner@fowler:LTC193379$
/home/bergner/gcc/build/gcc-fsf-mainline-ltc193379-debug/gcc/xgcc
-B/home/bergner/gcc/build/gcc-fsf-mainline-ltc193379-debug/gcc -S -O3 -UOK
-ftree-vectorize bug.c
bug.c: In function ‘foo’:
bug.c:13:12: warning: writing 1 byte into a region of size 0
[-Wstringop-overflow=]
   13 |     dst[i] = src[i];
      |     ~~~~~~~^~~~~~~~
bug.c:3:6: note: at offset 16 into destination object ‘dst’ of size 16
    3 | char dst[16];
      |      ^~~
bug.c:13:12: warning: writing 1 byte into a region of size 0
[-Wstringop-overflow=]
   13 |     dst[i] = src[i];
      |     ~~~~~~~^~~~~~~~
bug.c:3:6: note: at offset 17 into destination object ‘dst’ of size 16
    3 | char dst[16];
      |      ^~~

I'll note that -fno-unroll-loops doesn't affect anything.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug tree-optimization/106757] [12/13 Regression] Incorrect "writing 1 byte into a region of size 0" on a vectorized loop
  2022-08-26 18:32 [Bug c/106757] New: Incorrect "writing 1 byte into a region of size 0" warning jonathan.leffler at gmail dot com
                   ` (3 preceding siblings ...)
  2022-10-03 23:12 ` bergner at gcc dot gnu.org
@ 2022-10-19  7:05 ` rguenth at gcc dot gnu.org
  2022-12-05 20:35 ` rguenth at gcc dot gnu.org
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: rguenth at gcc dot gnu.org @ 2022-10-19  7:05 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106757

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P3                          |P2

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug tree-optimization/106757] [12/13 Regression] Incorrect "writing 1 byte into a region of size 0" on a vectorized loop
  2022-08-26 18:32 [Bug c/106757] New: Incorrect "writing 1 byte into a region of size 0" warning jonathan.leffler at gmail dot com
                   ` (4 preceding siblings ...)
  2022-10-19  7:05 ` rguenth at gcc dot gnu.org
@ 2022-12-05 20:35 ` rguenth at gcc dot gnu.org
  2023-05-08 12:25 ` [Bug tree-optimization/106757] [12/13/14 " rguenth at gcc dot gnu.org
  2024-03-15  1:08 ` [Bug tree-optimization/106757] [12/13 " law at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: rguenth at gcc dot gnu.org @ 2022-12-05 20:35 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106757

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |missed-optimization

--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Peter Bergner from comment #3)
> Is this the same bug, so just a simpler test case?
> 
> bergner@fowler:LTC193379$ cat bug.c
> int len = 16;
> extern char *src;
> char dst[16];
> 
> void
> foo (void)
> {
> #ifdef OK
>   for (int i = 0; i < 16; i++)
> #else
>   for (int i = 0; i < len; i++)
> #endif
>     dst[i] = src[i];
> }
> 
> bergner@fowler:LTC193379$
> /home/bergner/gcc/build/gcc-fsf-mainline-ltc193379-debug/gcc/xgcc
> -B/home/bergner/gcc/build/gcc-fsf-mainline-ltc193379-debug/gcc -S -O3 -DOK
> -ftree-vectorize bug.c
> 
> bergner@fowler:LTC193379$
> /home/bergner/gcc/build/gcc-fsf-mainline-ltc193379-debug/gcc/xgcc
> -B/home/bergner/gcc/build/gcc-fsf-mainline-ltc193379-debug/gcc -S -O3 -UOK
> -fno-tree-vectorize bug.c
> 
> bergner@fowler:LTC193379$
> /home/bergner/gcc/build/gcc-fsf-mainline-ltc193379-debug/gcc/xgcc
> -B/home/bergner/gcc/build/gcc-fsf-mainline-ltc193379-debug/gcc -S -O3 -UOK
> -ftree-vectorize bug.c
> bug.c: In function ‘foo’:
> bug.c:13:12: warning: writing 1 byte into a region of size 0
> [-Wstringop-overflow=]
>    13 |     dst[i] = src[i];
>       |     ~~~~~~~^~~~~~~~
> bug.c:3:6: note: at offset 16 into destination object ‘dst’ of size 16
>     3 | char dst[16];
>       |      ^~~
> bug.c:13:12: warning: writing 1 byte into a region of size 0
> [-Wstringop-overflow=]
>    13 |     dst[i] = src[i];
>       |     ~~~~~~~^~~~~~~~
> bug.c:3:6: note: at offset 17 into destination object ‘dst’ of size 16
>     3 | char dst[16];
>       |      ^~~
> 
> I'll note that -fno-unroll-loops doesn't affect anything.

It looks similar.  Note the code we warn is isolated by DOM threading
after loop opts here.  The unrolling done is also a bit excessive but
that's because we estimate an upper bound on the epilogue based on
the array size accessed.

The IL we diagnose is definitely bogus but unreachable at runtime which
we don't see so it's also a code size issue.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug tree-optimization/106757] [12/13/14 Regression] Incorrect "writing 1 byte into a region of size 0" on a vectorized loop
  2022-08-26 18:32 [Bug c/106757] New: Incorrect "writing 1 byte into a region of size 0" warning jonathan.leffler at gmail dot com
                   ` (5 preceding siblings ...)
  2022-12-05 20:35 ` rguenth at gcc dot gnu.org
@ 2023-05-08 12:25 ` rguenth at gcc dot gnu.org
  2024-03-15  1:08 ` [Bug tree-optimization/106757] [12/13 " law at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: rguenth at gcc dot gnu.org @ 2023-05-08 12:25 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106757

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Target Milestone|12.3                        |12.4

--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> ---
GCC 12.3 is being released, retargeting bugs to GCC 12.4.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug tree-optimization/106757] [12/13 Regression] Incorrect "writing 1 byte into a region of size 0" on a vectorized loop
  2022-08-26 18:32 [Bug c/106757] New: Incorrect "writing 1 byte into a region of size 0" warning jonathan.leffler at gmail dot com
                   ` (6 preceding siblings ...)
  2023-05-08 12:25 ` [Bug tree-optimization/106757] [12/13/14 " rguenth at gcc dot gnu.org
@ 2024-03-15  1:08 ` law at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: law at gcc dot gnu.org @ 2024-03-15  1:08 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106757

Jeffrey A. Law <law at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|[12/13/14 Regression]       |[12/13 Regression]
                   |Incorrect "writing 1 byte   |Incorrect "writing 1 byte
                   |into a region of size 0" on |into a region of size 0" on
                   |a vectorized loop           |a vectorized loop
                 CC|                            |law at gcc dot gnu.org

--- Comment #6 from Jeffrey A. Law <law at gcc dot gnu.org> ---
Works correctly on the trunk.  Adjusting regression markers.

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2024-03-15  1:08 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-26 18:32 [Bug c/106757] New: Incorrect "writing 1 byte into a region of size 0" warning jonathan.leffler at gmail dot com
2022-08-26 18:37 ` [Bug tree-optimization/106757] [12/13 Regression] " pinskia at gcc dot gnu.org
2022-08-26 19:21 ` [Bug tree-optimization/106757] [12/13 Regression] Incorrect "writing 1 byte into a region of size 0" on a vectorized loop msebor at gcc dot gnu.org
2022-08-29  8:26 ` rguenth at gcc dot gnu.org
2022-10-03 23:12 ` bergner at gcc dot gnu.org
2022-10-19  7:05 ` rguenth at gcc dot gnu.org
2022-12-05 20:35 ` rguenth at gcc dot gnu.org
2023-05-08 12:25 ` [Bug tree-optimization/106757] [12/13/14 " rguenth at gcc dot gnu.org
2024-03-15  1:08 ` [Bug tree-optimization/106757] [12/13 " law at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).