public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/108036] New: Spurious warning for zero-sized array parameters to a function
@ 2022-12-09 17:24 colomar.6.4.3 at gmail dot com
  2022-12-09 19:09 ` [Bug c/108036] " pinskia at gcc dot gnu.org
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: colomar.6.4.3 at gmail dot com @ 2022-12-09 17:24 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 108036
           Summary: Spurious warning for zero-sized array parameters to a
                    function
           Product: gcc
           Version: 12.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: colomar.6.4.3 at gmail dot com
  Target Milestone: ---

It's interesting to pass pointers to one past the end of an array to a
function, acting as a sentinel value that serves as an alternative to the size
of the buffer.  It helps chaining string copy functions, for example:


char *
ustr2stpe(char *dst, const char *restrict src, size_t n, char past_end[0])
{
        bool       trunc;
        char       *end;
        ptrdiff_t  len;

        if (dst == past_end)
                return past_end;

        trunc = false;
        len = strnlen(src, n);
        if (len > past_end - dst - 1) {
                len = past_end - dst - 1;
                trunc = true;
        }

        end = mempcpy(dst, src, len);
        *end = '\0';

        return trunc ? past_end : end;
}


However, if you use array syntax for it, which clarifies where it points to,
the GCC complains, not at the function implementation, but at call site:


#define nitems(arr)  (sizeof((arr)) / sizeof((arr)[0]))

int
main(void)
{
        char pre[4] = "pre.";
        char *post = ".post";
        char *src = "some-long-body.post";
        char dest[100];
         char *p, *past_end;

        past_end = dest + nitems(dest);
        p = dest;
        p = ustr2stpe(p, pre, nitems(pre), past_end);
        p = ustr2stpe(p, src, strlen(src) - strlen(post), past_end);
        p = ustr2stpe(p, "", 0, past_end);
        if (p == past_end)
                fprintf(stderr, "truncation\n");

        puts(dest);  // "pre.some-long-body"
}

$ cc -Wall -Wextra ustr2stpe.c
ustr2stpe.c: In function ‘main’:
ustr2stpe.c:43:13: warning: ‘ustr2stpe’ accessing 1 byte in a region of size 0
[-Wstringop-overflow=]
    43 |         p = ustr2stpe(p, pre, nitems(pre), past_end);
       |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ustr2stpe.c:43:13: note: referencing argument 4 of type ‘char[0]’
ustr2stpe.c:10:1: note: in a call to function ‘ustr2stpe’
    10 | ustr2stpe(char *dst, const char *restrict src, size_t n, char
past_end[0])
       | ^~~~~~~~~
ustr2stpe.c:44:13: warning: ‘ustr2stpe’ accessing 1 byte in a region of size 0
[-Wstringop-overflow=]
    44 |         p = ustr2stpe(p, src, strlen(src) - strlen(post), past_end);
       |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ustr2stpe.c:44:13: note: referencing argument 4 of type ‘char[0]’
ustr2stpe.c:10:1: note: in a call to function ‘ustr2stpe’
    10 | ustr2stpe(char *dst, const char *restrict src, size_t n, char
past_end[0])
       | ^~~~~~~~~
ustr2stpe.c:45:13: warning: ‘ustr2stpe’ accessing 1 byte in a region of size 0
[-Wstringop-overflow=]
    45 |         p = ustr2stpe(p, "", 0, past_end);
       |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ustr2stpe.c:45:13: note: referencing argument 4 of type ‘char[0]’
ustr2stpe.c:10:1: note: in a call to function ‘ustr2stpe’
    10 | ustr2stpe(char *dst, const char *restrict src, size_t n, char
past_end[0])
       | ^~~~~~~~~
ustr2stpe.c:43:13: warning: ‘ustr2stpe’ accessing 1 byte in a region of size 0
[-Wstringop-overflow=]
    43 |         p = ustr2stpe(p, pre, nitems(pre), past_end);
       |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ustr2stpe.c:43:13: note: referencing argument 4 of type ‘char[0]’
ustr2stpe.c:10:1: note: in a call to function ‘ustr2stpe’
    10 | ustr2stpe(char *dst, const char *restrict src, size_t n, char
past_end[0])
       | ^~~~~~~~~
ustr2stpe.c:44:13: warning: ‘ustr2stpe’ accessing 1 byte in a region of size 0
[-Wstringop-overflow=]
    44 |         p = ustr2stpe(p, src, strlen(src) - strlen(post), past_end);
       |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ustr2stpe.c:44:13: note: referencing argument 4 of type ‘char[0]’
ustr2stpe.c:10:1: note: in a call to function ‘ustr2stpe’
    10 | ustr2stpe(char *dst, const char *restrict src, size_t n, char
past_end[0])
       | ^~~~~~~~~
ustr2stpe.c:45:13: warning: ‘ustr2stpe’ accessing 1 byte in a region of size 0
[-Wstringop-overflow=]
    45 |         p = ustr2stpe(p, "", 0, past_end);
       |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ustr2stpe.c:45:13: note: referencing argument 4 of type ‘char[0]’
ustr2stpe.c:10:1: note: in a call to function ‘ustr2stpe’
    10 | ustr2stpe(char *dst, const char *restrict src, size_t n, char
past_end[0])
       | ^~~~~~~~~


The warnings are invalid.  While it's true that I'm referencing a pointer of
size 0, it's false that I'm "accessing 1 byte" in that region.  I guess this is
all about the bogus design of 'static' in ISO C, where you can have an array
parameter of size 0, which is very useful in cases like this one.


See the original report in the mailing list, where Richard Biener had some
guess of what might be the reason:
<https://gcc.gnu.org/pipermail/gcc/2022-December/240230.html>

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

* [Bug c/108036] Spurious warning for zero-sized array parameters to a function
  2022-12-09 17:24 [Bug c/108036] New: Spurious warning for zero-sized array parameters to a function colomar.6.4.3 at gmail dot com
@ 2022-12-09 19:09 ` pinskia at gcc dot gnu.org
  2022-12-09 19:13 ` [Bug middle-end/108036] [11/12/13 Regression] " pinskia at gcc dot gnu.org
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-12-09 19:09 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Created attachment 54055
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54055&action=edit
Full testcase that actually compiles

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

* [Bug middle-end/108036] [11/12/13 Regression] Spurious warning for zero-sized array parameters to a function
  2022-12-09 17:24 [Bug c/108036] New: Spurious warning for zero-sized array parameters to a function colomar.6.4.3 at gmail dot com
  2022-12-09 19:09 ` [Bug c/108036] " pinskia at gcc dot gnu.org
@ 2022-12-09 19:13 ` pinskia at gcc dot gnu.org
  2022-12-09 19:13 ` pinskia at gcc dot gnu.org
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-12-09 19:13 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Created attachment 54056
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54056&action=edit
Reduced testcase

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

* [Bug middle-end/108036] [11/12/13 Regression] Spurious warning for zero-sized array parameters to a function
  2022-12-09 17:24 [Bug c/108036] New: Spurious warning for zero-sized array parameters to a function colomar.6.4.3 at gmail dot com
  2022-12-09 19:09 ` [Bug c/108036] " pinskia at gcc dot gnu.org
  2022-12-09 19:13 ` [Bug middle-end/108036] [11/12/13 Regression] " pinskia at gcc dot gnu.org
@ 2022-12-09 19:13 ` pinskia at gcc dot gnu.org
  2022-12-09 19:18 ` colomar.6.4.3 at gmail dot com
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-12-09 19:13 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Target Milestone|---                         |11.4
     Ever confirmed|0                           |1
   Last reconfirmed|                            |2022-12-09

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

* [Bug middle-end/108036] [11/12/13 Regression] Spurious warning for zero-sized array parameters to a function
  2022-12-09 17:24 [Bug c/108036] New: Spurious warning for zero-sized array parameters to a function colomar.6.4.3 at gmail dot com
                   ` (2 preceding siblings ...)
  2022-12-09 19:13 ` pinskia at gcc dot gnu.org
@ 2022-12-09 19:18 ` colomar.6.4.3 at gmail dot com
  2022-12-09 19:22 ` pinskia at gcc dot gnu.org
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: colomar.6.4.3 at gmail dot com @ 2022-12-09 19:18 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Alejandro Colomar <colomar.6.4.3 at gmail dot com> ---
Hi Andrew!

Just a few nitpicks:

-  In the first testcase you posted, the [] is missing the 0: [0].

-  In the reduced test case, you call the pointer to one past the end as 'end'.
 That is misleading, since 'end' is commonly also used for pointers to the last
byte in an array, normally the NUL byte in strings.  Using the term 'end'
meaning one-past-the-end is likely to end up in off-by-one errors.  So much
that I found a few of them for exactly that reason this week :)

This last point is why I like using array syntax, so I can clrealy specify
'end[1]' and 'past_end[0]', and they are clearly different things.

Cheers,

Alex

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

* [Bug middle-end/108036] [11/12/13 Regression] Spurious warning for zero-sized array parameters to a function
  2022-12-09 17:24 [Bug c/108036] New: Spurious warning for zero-sized array parameters to a function colomar.6.4.3 at gmail dot com
                   ` (3 preceding siblings ...)
  2022-12-09 19:18 ` colomar.6.4.3 at gmail dot com
@ 2022-12-09 19:22 ` pinskia at gcc dot gnu.org
  2022-12-09 19:23 ` colomar.6.4.3 at gmail dot com
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-12-09 19:22 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Alejandro Colomar from comment #3)
> -  In the reduced test case, you call the pointer to one past the end as
> 'end'.  That is misleading, since 'end' is commonly also used for pointers
> to the last byte in an array, normally the NUL byte in strings. 

In the C++ standard, the function end() returns one past the last element of an
array. So I am not misusing the name end here. Just using it different from
you.

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

* [Bug middle-end/108036] [11/12/13 Regression] Spurious warning for zero-sized array parameters to a function
  2022-12-09 17:24 [Bug c/108036] New: Spurious warning for zero-sized array parameters to a function colomar.6.4.3 at gmail dot com
                   ` (4 preceding siblings ...)
  2022-12-09 19:22 ` pinskia at gcc dot gnu.org
@ 2022-12-09 19:23 ` colomar.6.4.3 at gmail dot com
  2022-12-21 11:45 ` rguenth at gcc dot gnu.org
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: colomar.6.4.3 at gmail dot com @ 2022-12-09 19:23 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #5 from Alejandro Colomar <colomar.6.4.3 at gmail dot com> ---
Interesting.  Thanks for clarifying :)

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

* [Bug middle-end/108036] [11/12/13 Regression] Spurious warning for zero-sized array parameters to a function
  2022-12-09 17:24 [Bug c/108036] New: Spurious warning for zero-sized array parameters to a function colomar.6.4.3 at gmail dot com
                   ` (5 preceding siblings ...)
  2022-12-09 19:23 ` colomar.6.4.3 at gmail dot com
@ 2022-12-21 11:45 ` rguenth at gcc dot gnu.org
  2023-05-29 10:07 ` [Bug middle-end/108036] [11/12/13/14 " jakub at gcc dot gnu.org
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: rguenth at gcc dot gnu.org @ 2022-12-21 11:45 UTC (permalink / raw)
  To: gcc-bugs

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

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

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

--- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> ---
I read Martins response on the mailing list as if special-casing T[0] would be
OK and that this is simply missed right now.

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

* [Bug middle-end/108036] [11/12/13/14 Regression] Spurious warning for zero-sized array parameters to a function
  2022-12-09 17:24 [Bug c/108036] New: Spurious warning for zero-sized array parameters to a function colomar.6.4.3 at gmail dot com
                   ` (6 preceding siblings ...)
  2022-12-21 11:45 ` rguenth at gcc dot gnu.org
@ 2023-05-29 10:07 ` jakub at gcc dot gnu.org
  2024-03-07 10:18 ` daniel.lundin.mail at gmail dot com
  2024-03-07 10:53 ` alx at kernel dot org
  9 siblings, 0 replies; 11+ messages in thread
From: jakub at gcc dot gnu.org @ 2023-05-29 10:07 UTC (permalink / raw)
  To: gcc-bugs

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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Target Milestone|11.4                        |11.5

--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
GCC 11.4 is being released, retargeting bugs to GCC 11.5.

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

* [Bug middle-end/108036] [11/12/13/14 Regression] Spurious warning for zero-sized array parameters to a function
  2022-12-09 17:24 [Bug c/108036] New: Spurious warning for zero-sized array parameters to a function colomar.6.4.3 at gmail dot com
                   ` (7 preceding siblings ...)
  2023-05-29 10:07 ` [Bug middle-end/108036] [11/12/13/14 " jakub at gcc dot gnu.org
@ 2024-03-07 10:18 ` daniel.lundin.mail at gmail dot com
  2024-03-07 10:53 ` alx at kernel dot org
  9 siblings, 0 replies; 11+ messages in thread
From: daniel.lundin.mail at gmail dot com @ 2024-03-07 10:18 UTC (permalink / raw)
  To: gcc-bugs

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

Daniel Lundin <daniel.lundin.mail at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |daniel.lundin.mail at gmail dot co
                   |                            |m

--- Comment #8 from Daniel Lundin <daniel.lundin.mail at gmail dot com> ---
I don't believe char past_end[0] is valid C, because it is an invalid array
declaration. Unlike [] or [*] that declares an array of incomplete type. 

Since it is a function parameter, it will of course later get adjusted to a
pointer to the first element. But it still has to be a valid declaration to
begin with. Similarly, char arr[][] is invalid because it remains an incomplete
type after adjustment (see C17 6.7.6.4 §4).

gcc does allow [0] as an extension since that was commonly used for purposes of
implementing the "struct hack" back in the days before flexible array members
were standardized.

The conclusion ought to be that gcc should let [0] through if compiled in
-std=gnu23 mode but not in -std=c23 and/or -pedantic.

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

* [Bug middle-end/108036] [11/12/13/14 Regression] Spurious warning for zero-sized array parameters to a function
  2022-12-09 17:24 [Bug c/108036] New: Spurious warning for zero-sized array parameters to a function colomar.6.4.3 at gmail dot com
                   ` (8 preceding siblings ...)
  2024-03-07 10:18 ` daniel.lundin.mail at gmail dot com
@ 2024-03-07 10:53 ` alx at kernel dot org
  9 siblings, 0 replies; 11+ messages in thread
From: alx at kernel dot org @ 2024-03-07 10:53 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #9 from Alejandro Colomar <alx at kernel dot org> ---
Hi Lundin!

On Thu, Mar 07, 2024 at 10:18:12AM +0000, daniel.lundin.mail at gmail dot com
wrote:
> --- Comment #8 from Daniel Lundin <daniel.lundin.mail at gmail dot com> ---
> I don't believe char past_end[0] is valid C, because it is an invalid array
> declaration. Unlike [] or [*] that declares an array of incomplete type. 
> 
> Since it is a function parameter, it will of course later get adjusted to a
> pointer to the first element. But it still has to be a valid declaration to
> begin with. Similarly, char arr[][] is invalid because it remains an incomplete
> type after adjustment (see C17 6.7.6.4 §4).

Agree; ISO C seems to not allow this with their wording.  (I wish it did,
because it's just a matter of wording, not that they don't allow passing
a pointer to past the end).  But maybe the wording needed for allowing
this would have other undersirable consequences, so I'm happy as long as
GNU C would support this.

> gcc does allow [0] as an extension since that was commonly used for purposes of
> implementing the "struct hack" back in the days before flexible array members
> were standardized.
> 
> The conclusion ought to be that gcc should let [0] through if compiled in
> -std=gnu23 mode but not in -std=c23 and/or -pedantic.

And agree; if support for this is added, pedantic or ISO C modes should
complain about it.

Have a lovely day!
Alex

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

end of thread, other threads:[~2024-03-07 10:53 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-09 17:24 [Bug c/108036] New: Spurious warning for zero-sized array parameters to a function colomar.6.4.3 at gmail dot com
2022-12-09 19:09 ` [Bug c/108036] " pinskia at gcc dot gnu.org
2022-12-09 19:13 ` [Bug middle-end/108036] [11/12/13 Regression] " pinskia at gcc dot gnu.org
2022-12-09 19:13 ` pinskia at gcc dot gnu.org
2022-12-09 19:18 ` colomar.6.4.3 at gmail dot com
2022-12-09 19:22 ` pinskia at gcc dot gnu.org
2022-12-09 19:23 ` colomar.6.4.3 at gmail dot com
2022-12-21 11:45 ` rguenth at gcc dot gnu.org
2023-05-29 10:07 ` [Bug middle-end/108036] [11/12/13/14 " jakub at gcc dot gnu.org
2024-03-07 10:18 ` daniel.lundin.mail at gmail dot com
2024-03-07 10:53 ` alx at kernel dot 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).