public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug middle-end/108154] New: Inappropriate -Wstringop-overread in the C99 [static n] func decl
@ 2022-12-17 10:14 roman.zilka at gmail dot com
  2022-12-17 13:40 ` [Bug c/108154] Inappropriate -Wstringop-overread in the C99 [static n] func param decl roman.zilka at gmail dot com
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: roman.zilka at gmail dot com @ 2022-12-17 10:14 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 108154
           Summary: Inappropriate -Wstringop-overread in the C99 [static
                    n] func decl
           Product: gcc
           Version: 11.3.1
            Status: UNCONFIRMED
          Keywords: diagnostic
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: roman.zilka at gmail dot com
  Target Milestone: ---
              Host: x86_64-pc-linux-gnu
            Target: x86_64-pc-linux-gnu
             Build: x86_64-pc-linux-gnu

Created attachment 54116
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54116&action=edit
gcc -v

GCC issues Wstringop-overread when a function declared with "buffer[static n]"
reads past the n-th item of the buffer.


$ cat test.c
#include <string.h>
void f(char s[static 1]) {
        ++s;
        if (strchr(s, 'a')) ++*s;
}
int main() {
        char s[10] = {0};
        f(s);
}

$ gcc -O1 test.c
test.c: In function ‘f’:
test.c:4:13: warning: ‘strchr’ reading 1 or more bytes from a region of size 0
[-Wstringop-overread]
    4 |         if (strchr(s, 'a')) ++*s;
      |             ^~~~~~~~~~~~~~
test.c:2:13: note: at offset 1 into source object ‘s’ of size [0, 1]
    2 | void f(char s[static 1]) {
      |        ~~~~~^~~~~~~~~~~


That may be a correct read, though, as 'n' is the size lower bound. Sure, it's
idiomatic to understand the phrase "the size of 'buffer' is at least 'n'" (as
C99 defines this type of declaration) as "this function operates on up to 'n'
items and doesn't care what's after that bound". This syntax is useful,
however, as "buffer[static 1]" to advertise to the compiler and the function
user that a non-NULL ptr must be passed.

I have a few functions in a sourcefile that handle 0-term. strings and make use
of that. The string length is not passed in another argument, so I can't use
"f(size_t n, char buffer[static n])". The amount of false-positive
Wstringop-overreads is so large it's not even helpful to use "pragma diagnostic
ignored" and I just disable the warning altogether, which is sub-ideal. As much
as I hate the syntax, after 23 years it looks like it's in the language to stay
and it's just too damn useful for documentation and code optimization (bug
102556). I'm actually surprised that so few people make use of it, although the
ugliness of it does provide a lead.

Please consider exempting this kind of declaration from Wstringop-overread.
Similar: bug 104854.

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

* [Bug c/108154] Inappropriate -Wstringop-overread in the C99 [static n] func param decl
  2022-12-17 10:14 [Bug middle-end/108154] New: Inappropriate -Wstringop-overread in the C99 [static n] func decl roman.zilka at gmail dot com
@ 2022-12-17 13:40 ` roman.zilka at gmail dot com
  2022-12-19  8:03 ` [Bug middle-end/108154] " rguenth at gcc dot gnu.org
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: roman.zilka at gmail dot com @ 2022-12-17 13:40 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #1 from Roman Žilka <roman.zilka at gmail dot com> ---
If the object size derivation procedure, which considers 's' to be 0-1 bytes
here, isn't specific just to Wstringop-overread, there's one more issue in gcc,
of course.

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

* [Bug middle-end/108154] Inappropriate -Wstringop-overread in the C99 [static n] func param decl
  2022-12-17 10:14 [Bug middle-end/108154] New: Inappropriate -Wstringop-overread in the C99 [static n] func decl roman.zilka at gmail dot com
  2022-12-17 13:40 ` [Bug c/108154] Inappropriate -Wstringop-overread in the C99 [static n] func param decl roman.zilka at gmail dot com
@ 2022-12-19  8:03 ` rguenth at gcc dot gnu.org
  2022-12-20  0:06 ` msebor at gcc dot gnu.org
  2022-12-20 10:13 ` roman.zilka at gmail dot com
  3 siblings, 0 replies; 5+ messages in thread
From: rguenth at gcc dot gnu.org @ 2022-12-19  8:03 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jsm28 at gcc dot gnu.org,
                   |                            |msebor at gcc dot gnu.org,
                   |                            |rguenth at gcc dot gnu.org

--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
Indeed 6.7.6.3/7 says "shall provide access to the first element of an array
with AT LEAST as many elements as specified by the size expression", so
interpreting the '1' in char s[static 1] as an upper bound for the size is
wrong?

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

* [Bug middle-end/108154] Inappropriate -Wstringop-overread in the C99 [static n] func param decl
  2022-12-17 10:14 [Bug middle-end/108154] New: Inappropriate -Wstringop-overread in the C99 [static n] func decl roman.zilka at gmail dot com
  2022-12-17 13:40 ` [Bug c/108154] Inappropriate -Wstringop-overread in the C99 [static n] func param decl roman.zilka at gmail dot com
  2022-12-19  8:03 ` [Bug middle-end/108154] " rguenth at gcc dot gnu.org
@ 2022-12-20  0:06 ` msebor at gcc dot gnu.org
  2022-12-20 10:13 ` roman.zilka at gmail dot com
  3 siblings, 0 replies; 5+ messages in thread
From: msebor at gcc dot gnu.org @ 2022-12-20  0:06 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |INVALID
             Status|UNCONFIRMED                 |RESOLVED

--- Comment #3 from Martin Sebor <msebor at gcc dot gnu.org> ---
The warning here is intentional -- as noted, a [static 1] array can be as small
as a single element.  The warning is designed to help detect stronger
assumptions inadvertently made by the function definition.  (The compiler makes
no analysis to see how the function is being called; it could if the function
were declared static but but without full LTO it can't for an extern function.)

The recommended annotation to indicate that a pointer argument must not be null
is attribute nonnull.

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

* [Bug middle-end/108154] Inappropriate -Wstringop-overread in the C99 [static n] func param decl
  2022-12-17 10:14 [Bug middle-end/108154] New: Inappropriate -Wstringop-overread in the C99 [static n] func decl roman.zilka at gmail dot com
                   ` (2 preceding siblings ...)
  2022-12-20  0:06 ` msebor at gcc dot gnu.org
@ 2022-12-20 10:13 ` roman.zilka at gmail dot com
  3 siblings, 0 replies; 5+ messages in thread
From: roman.zilka at gmail dot com @ 2022-12-20 10:13 UTC (permalink / raw)
  To: gcc-bugs

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

Roman Žilka <roman.zilka at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|INVALID                     |---
             Status|RESOLVED                    |UNCONFIRMED

--- Comment #4 from Roman Žilka <roman.zilka at gmail dot com> ---
So be it, as for the application of Wstring-overread. But gcc doesn't use the
integer following "static" as a definite indication of the size upper bound for
any other purpose (code optimization, ...), does it? C (C99, anyway) merely
states that the size of the array shall be at least 'n'. I'm asking because the
part of the quoted error message, which talks about the size of 's', suggests
that gcc may internally consider 's' to be 1 or fewer chars large. Considering
a size >n impossible may, in theory, lead to incorrect unreachability
assertions. Considering a size <n possible may limit optimization (like bug
102556).

By the way, C9X Rationale WG14/N897, 6.7.5.2, gives optimization as the
motivation for the [static n] construct. Of course, security over optimization.

Let me correct myself for the record: f(size_t n, char buffer[static n]) is
equivalent to just "char *buffer", if I'm reading it right. That was not a
valid use case.

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

end of thread, other threads:[~2022-12-20 10:13 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-17 10:14 [Bug middle-end/108154] New: Inappropriate -Wstringop-overread in the C99 [static n] func decl roman.zilka at gmail dot com
2022-12-17 13:40 ` [Bug c/108154] Inappropriate -Wstringop-overread in the C99 [static n] func param decl roman.zilka at gmail dot com
2022-12-19  8:03 ` [Bug middle-end/108154] " rguenth at gcc dot gnu.org
2022-12-20  0:06 ` msebor at gcc dot gnu.org
2022-12-20 10:13 ` roman.zilka at gmail dot com

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).