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.

Reply via email to