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.

Reply via email to