public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug tree-optimization/108091] New: '-Wformat-overflow' determines incorrect size when printing strings from an array of structs
@ 2022-12-14  2:18 cjamcl at gmail dot com
  2022-12-14  2:26 ` [Bug tree-optimization/108091] " pinskia at gcc dot gnu.org
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: cjamcl at gmail dot com @ 2022-12-14  2:18 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 108091
           Summary: '-Wformat-overflow' determines incorrect size when
                    printing strings from an array of structs
           Product: gcc
           Version: 12.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: cjamcl at gmail dot com
  Target Milestone: ---

Given an array of structs for which a member is a `char[]`, `-Wformat-overflow`
will be far too conservative in its determination of how big the printed value
can be.


Repro:

https://gcc.godbolt.org/z/K69baxW55

```c
// gcc -Os -Wformat-overflow -c test.c

struct my_struct
{
    char name[64];
    int id;
};

struct my_struct list[]=
{
        { "A", 0},
    { "B", 0},
    { "C", 0},
    { "",  0},
};

int main() {
    char str[100];

    for (int i = 0; i < 4; i++) {
        __builtin_sprintf(str, "%s", list[i].name);
    }

    return 0;
}
```

Output:

```
<source>: In function 'int main()':
<source>:19:33: warning: '%s' directive writing up to 271 bytes into a region
of size 100 [-Wformat-overflow=]
   19 |         __builtin_sprintf(str, "%s", list[i].name);
      |                                 ^~
<source>:19:26: note: '__builtin_sprintf' output between 1 and 272 bytes into a
destination of size 100
   19 |         __builtin_sprintf(str, "%s", list[i].name);
      |         ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
Compiler returned: 0
```


-----

My assumption is that it cannot be determined that some value doesn't get a
non-null terminated string written to it at runtime, so the check is very
conservative and gives a length equal to the full size of the array.

In the above example, I'd expect gcc to know that the values are never
re-assigned, so it should use the length of whatever the biggest string in the
array is. I attempted to help the check by adding `const` qualifiers but that
didn't help.

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

* [Bug tree-optimization/108091] '-Wformat-overflow' determines incorrect size when printing strings from an array of structs
  2022-12-14  2:18 [Bug tree-optimization/108091] New: '-Wformat-overflow' determines incorrect size when printing strings from an array of structs cjamcl at gmail dot com
@ 2022-12-14  2:26 ` pinskia at gcc dot gnu.org
  2022-12-14  2:28 ` pinskia at gcc dot gnu.org
  2022-12-14  8:01 ` jakub at gcc dot gnu.org
  2 siblings, 0 replies; 4+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-12-14  2:26 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|                            |2022-12-14
     Ever confirmed|0                           |1
             Status|UNCONFIRMED                 |NEW

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
IV-OPTS produces:
  <bb 3> [local count: 858993457]:
  # ivtmp.10_13 = PHI <ivtmp.10_14(5), ivtmp.10_15(2)>
  _1 = (char[64] *) ivtmp.10_13;
  __builtin_strcpy (&str, _1);
  ivtmp.10_14 = ivtmp.10_13 + 68;
  if (ivtmp.10_14 != _17)
    goto <bb 5>; [80.00%]
  else
    goto <bb 4>; [20.00%]

  <bb 5> [local count: 687194763]:
  goto <bb 3>; [100.00%]

Which confuses the warning pass.

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

* [Bug tree-optimization/108091] '-Wformat-overflow' determines incorrect size when printing strings from an array of structs
  2022-12-14  2:18 [Bug tree-optimization/108091] New: '-Wformat-overflow' determines incorrect size when printing strings from an array of structs cjamcl at gmail dot com
  2022-12-14  2:26 ` [Bug tree-optimization/108091] " pinskia at gcc dot gnu.org
@ 2022-12-14  2:28 ` pinskia at gcc dot gnu.org
  2022-12-14  8:01 ` jakub at gcc dot gnu.org
  2 siblings, 0 replies; 4+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-12-14  2:28 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |DUPLICATE
             Status|NEW                         |RESOLVED

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Dup of bug 106559 (the underlying problem is the same).

*** This bug has been marked as a duplicate of bug 106559 ***

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

* [Bug tree-optimization/108091] '-Wformat-overflow' determines incorrect size when printing strings from an array of structs
  2022-12-14  2:18 [Bug tree-optimization/108091] New: '-Wformat-overflow' determines incorrect size when printing strings from an array of structs cjamcl at gmail dot com
  2022-12-14  2:26 ` [Bug tree-optimization/108091] " pinskia at gcc dot gnu.org
  2022-12-14  2:28 ` pinskia at gcc dot gnu.org
@ 2022-12-14  8:01 ` jakub at gcc dot gnu.org
  2 siblings, 0 replies; 4+ messages in thread
From: jakub at gcc dot gnu.org @ 2022-12-14  8:01 UTC (permalink / raw)
  To: gcc-bugs

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

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

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

--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Connor Clark from comment #0)
> In the above example, I'd expect gcc to know that the values are never
> re-assigned

That is an incorrect expectation.  list is a global variable, so it could be
changed
from any other translation unit, e.g. from __attribute__((constructor)) code or
C++ constructor of a namespace variable.

Though yes, making it const or as in PR106559 a static array allows the
compiler to see it isn't changed and it does warn anyway.

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

end of thread, other threads:[~2022-12-14  8:01 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-14  2:18 [Bug tree-optimization/108091] New: '-Wformat-overflow' determines incorrect size when printing strings from an array of structs cjamcl at gmail dot com
2022-12-14  2:26 ` [Bug tree-optimization/108091] " pinskia at gcc dot gnu.org
2022-12-14  2:28 ` pinskia at gcc dot gnu.org
2022-12-14  8:01 ` jakub 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).