https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79352
Bug ID: 79352 Summary: [6 Regression] -fprintf-return-value doesn't handle flexible-like array members properly Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: jakub at gcc dot gnu.org Target Milestone: --- Most of the optimization passes handle flexible array members and trailing arrays in structures that could be poor man's flexible array members conservatively, but apparently gimple-ssa-sprintf.c does not. char buf[64]; struct S { int i; char j[1]; }; __attribute__((noinline, noclone)) void foo (struct S *p) { int a = __builtin_sprintf (buf, "a%sf", p->j); if (a != 6) __builtin_abort (); } int main () { struct S *s = __builtin_malloc (sizeof (struct S) + 4); if (s) { s->i = 5; __builtin_strcpy (s->j, "bcde"); foo (s); __builtin_free (s); } return 0; } ICEs because of that, the pass thinks that p->j must be "", while in foo it can be arbitrary length. If you try to print __builtin_object_size (s->j, {0,1}) before the call to foo, it prints 8 (that is sizeof (struct S) + 4 - offsetof (struct S, s->j[0])), if you try to print __builtin_object_size (p->j, {0,1}) inside of foo, it will correctly print -1, don't know length.