https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86085
Bug ID: 86085
Summary: I/O built-ins considered argument clobbers
Product: gcc
Version: 8.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: msebor at gcc dot gnu.org
Target Milestone: ---
The buggy test case in pr67610 should be diagnosed by -Wrestrict but isn't.
Debugging shows that the strlen pass discards the length information for the
array in g() in response to the alias oracle determining that the printf() call
might clobber the array argument. Except for printf with the %n directive,
standard output functions don't modify their arguments.
$ cat z.c && gcc -O2 -S -Wall -Wextra -fdump-tree-optimized=/dev/stdout z.c
void f (void)
{
char s[] = "123";
char d[sizeof s];
__builtin_sprintf (d, "%s", s); // eliminated (transformed to strcpy by
sprintf pass)
if (__builtin_strlen (s) != 3) // folded
__builtin_abort ();
if (__builtin_strlen (d) != 3) // also folded
__builtin_abort ();
}
void g (void)
{
char s[] = "123";
__builtin_puts (s);
if (__builtin_strlen (s) != 3) // not folded
__builtin_abort ();
}
;; Function f (f, funcdef_no=0, decl_uid=1956, cgraph_uid=0, symbol_order=0)
f ()
{
<bb 2> [local count: 1073741825]:
return;
}
;; Function g (g, funcdef_no=1, decl_uid=1961, cgraph_uid=1, symbol_order=1)
g ()
{
char s[4];
long unsigned int _1;
<bb 2> [local count: 1073741825]:
s = "123";
__builtin_puts (&s);
_1 = __builtin_strlen (&s);
if (_1 != 3)
goto <bb 3>; [0.00%]
else
goto <bb 4>; [99.96%]
<bb 3> [count: 0]:
__builtin_abort ();
<bb 4> [local count: 1073312327]:
s ={v} {CLOBBER};
return;
}