Bug 101397 - [11 Regression] spurious warning writing to the result of stpcpy minus 1
Summary: [11 Regression] spurious warning writing to the result of stpcpy minus 1
Status: ASSIGNED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 11.1.0
: P3 normal
Target Milestone: 11.5
Assignee: Martin Sebor
URL:
Keywords: diagnostic, patch
: 101415 (view as bug list)
Depends on: 103143
Blocks: Warray-bounds Wstringop-overflow
  Show dependency treegraph
 
Reported: 2021-07-09 18:23 UTC by Martin Sebor
Modified: 2023-05-29 10:05 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 11.1.0
Last reconfirmed: 2021-07-09 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Sebor 2021-07-09 18:23:08 UTC
This is reduced from a recent Glibc build with GCC 12 which shows the warning below:

In function ‘nis_local_group’,
    inlined from ‘nis_local_group’ at nis_local_names.c:27:1:
nis_local_names.c:38:13: error: array subscript -1 is outside array bounds of ‘char[1025]’ [-Werror=array-bounds]
   38 |       if (cp[-1] != '.')
      |           ~~^~~~
nis_local_names.c: In function ‘nis_local_group’:
nis_local_names.c:29:15: note: at offset -1 into object ‘__nisgroup’ of size 1025
   29 |   static char __nisgroup[NIS_MAXNAMELEN + 1];
      |               ^~~~~~~~~~

The following test case shows the warning is a false positive.  Since stpcpy() returns a pointer to the terminating null it appends to the destination neither of the warnings below is appropriate since there's no indication that the copied string is empty.  The output below is with GCC 11.1.  In GCC 12 the second -Wstringop-overflow becomes a -Warray-bounds.

$ cat t.c && gcc -O2 -S -Wall t.c
void f (void*);

void g (const char *s)
{
  char d[8];
  char *t = __builtin_stpcpy (d, s);
  __builtin_strcpy (t - 1, "x");
  f (d);
}

void h (const char *s)
{
  char d[8];
  char *t = __builtin_stpcpy (d, s);
  t[-1] = 0;
  f (d);
}

t.c: In function ‘g’:
t.c:7:3: warning: ‘__builtin_memcpy’ writing 2 bytes into a region of size 0 overflows the destination [-Wstringop-overflow=]
    7 |   __builtin_strcpy (t - 1, "x");
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
t.c:5:8: note: at offset -1 into destination object ‘d’ of size 8
    5 |   char d[8];
      |        ^
t.c: In function ‘h’:
t.c:15:9: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
   15 |   t[-1] = 0;
      |   ~~~~~~^~~
t.c:13:8: note: at offset -1 into destination object ‘d’ of size 8
   13 |   char d[8];
      |        ^
Comment 1 Martin Sebor 2021-07-09 18:25:46 UTC
The warning was introduced in g:83685efd5fd1623cfc4e4c435ce2773d95d458d1.
Comment 2 Martin Sebor 2021-07-12 17:20:26 UTC
*** Bug 101415 has been marked as a duplicate of this bug. ***
Comment 4 GCC Commits 2021-07-20 19:52:17 UTC
The master branch has been updated by Martin Sebor <msebor@gcc.gnu.org>:

https://gcc.gnu.org/g:8bf5b49ebd2176b8c535147377381dd07fbdd643

commit r12-2422-g8bf5b49ebd2176b8c535147377381dd07fbdd643
Author: Martin Sebor <msebor@redhat.com>
Date:   Tue Jul 20 13:48:20 2021 -0600

    Correct stpcpy offset computation for -Warray-bounds et al. [PR101397].
    
    Resolves:
    PR middle-end/101397 - spurious warning writing to the result of stpcpy minus 1
    
    gcc/ChangeLog:
    
            PR middle-end/101397
            * builtins.c (gimple_call_return_array): Add argument.  Correct
            offsets for memchr, mempcpy, stpcpy, and stpncpy.
            (compute_objsize_r): Adjust offset computation for argument returning
            built-ins.
    
    gcc/testsuite/ChangeLog:
    
            PR middle-end/101397
            * gcc.dg/Warray-bounds-80.c: New test.
            * gcc.dg/Warray-bounds-81.c: New test.
            * gcc.dg/Warray-bounds-82.c: New test.
            * gcc.dg/Warray-bounds-83.c: New test.
            * gcc.dg/Warray-bounds-84.c: New test.
            * gcc.dg/Wstringop-overflow-46.c: Adjust expected output.
Comment 5 Martin Sebor 2021-07-20 19:53:44 UTC
Fixed in GCC 12.0.  Will backport to 11 after a bit.
Comment 6 Richard Biener 2021-07-28 07:07:30 UTC
GCC 11.2 is being released, retargeting bugs to GCC 11.3
Comment 7 Siddhesh Poyarekar 2021-10-26 14:24:12 UTC
(In reply to CVS Commits from comment #4)
> The master branch has been updated by Martin Sebor <msebor@gcc.gnu.org>:
> 
> https://gcc.gnu.org/g:8bf5b49ebd2176b8c535147377381dd07fbdd643
> 
> commit r12-2422-g8bf5b49ebd2176b8c535147377381dd07fbdd643
> Author: Martin Sebor <msebor@redhat.com>
> Date:   Tue Jul 20 13:48:20 2021 -0600
> 
>     Correct stpcpy offset computation for -Warray-bounds et al. [PR101397].

This causes a crash with the following program due to an infinite recursion:

typedef __SIZE_TYPE__ size_t;

void
__attribute__ ((noinline))
foo (size_t x)
{
  struct T { char buf[64]; char buf2[64]; } t;
  char *p = &t.buf[8];
  char *r = t.buf2;
  size_t i;

  for (i = 0; i < x; i++)
    {
      r = __builtin_mempcpy (r, p, i);
      p = r + 1;
    }
}

$ cc1.r12-2422 -quiet -o - repro.c 
        .file   "repro.c"
        .text
Segmentation fault (core dumped)
Comment 8 Martin Sebor 2021-11-09 00:06:56 UTC
(In reply to Siddhesh Poyarekar from comment #7)

Thanks.  I opened pr103143 for this GCC 12 regression.
Comment 9 Richard Biener 2022-04-21 07:49:56 UTC
GCC 11.3 is being released, retargeting bugs to GCC 11.4.
Comment 10 Jakub Jelinek 2023-05-29 10:05:18 UTC
GCC 11.4 is being released, retargeting bugs to GCC 11.5.