https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61886
Bug ID: 61886 Summary: [4.8/4.9/4.10 Regression] LTO breaks fread with _FORTIFY_SOURCE=2 Product: gcc Version: 4.9.1 Status: UNCONFIRMED Keywords: diagnostic, lto, wrong-code Severity: normal Priority: P3 Component: lto Assignee: unassigned at gcc dot gnu.org Reporter: rguenth at gcc dot gnu.org CC: hubicka at gcc dot gnu.org Created attachment 33176 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=33176&action=edit testcase extracted from cairo test suite With the attached testcase extracted from the Cairo testsuite (which they build with -flto ...) you get > gcc-4.9 create-for-stream.i -O2 -flto -r -nostdlib In function ‘__fread_alias’, inlined from ‘test_surface’ at create-for-stream.c:218:9: /usr/include/bits/stdio2.h:290:2: warning: call to ‘__fread_chk_warn’ declared with attribute warning: fread called with bigger size * nmemb than length of destination buffer return __fread_chk (__ptr, __bos0 (__ptr), __size, __n, __stream); ^ where we mangle compile-time <bb 13>: _55 = wc.index; _77 = __builtin_constant_p (_55); if (_77 == 0) goto <bb 15>; else goto <bb 14>; <bb 14>: _78 = _55 | 1; if (_78 > 4294967295) goto <bb 15>; else goto <bb 16>; <bb 15>: _79 = __fread_chk (&file_contents, 4096, 1, _55, fp_48); goto <bb 19>; <bb 16>: if (_55 > 4096) goto <bb 17>; else goto <bb 18>; <bb 17>: _81 = *__fread_chk (&file_contents, 4096, 1, _55, fp_48); goto <bb 19>; <bb 18>: _82 = *fread (&file_contents, 1, _55, fp_48); <bb 19>: # _83 = PHI <_79(15), _81(17), _82(18)> into the bogus <bb 13>: _49 = wc.index; _64 = __builtin_constant_p (_49); if (_64 == 0) goto <bb 15>; else goto <bb 14>; <bb 14>: _65 = _49 | 1; if (_65 > 4294967295) goto <bb 15>; else goto <bb 16>; <bb 15>: _66 = __fread_chk_warn (&file_contents, 4096, 1, _49, fp_43); goto <bb 19>; <bb 16>: if (_49 > 4096) goto <bb 17>; else goto <bb 18>; <bb 17>: _67 = __fread_chk_warn (&file_contents, 4096, 1, _49, fp_43); goto <bb 19>; <bb 18>: _68 = __fread_alias (&file_contents, 1, _49, fp_43); <bb 19>: # _69 = PHI <_66(15), _67(17), _68(18)> somehow messing up the aliases game glibc plays: extern size_t __fread_chk (void *__restrict __ptr, size_t __ptrlen, size_t __size, size_t __n, FILE *__restrict __stream) __wur; extern size_t __REDIRECT (__fread_alias, (void *__restrict __ptr, size_t __size, size_t __n, FILE *__restrict __stream), fread) __wur; extern size_t __REDIRECT (__fread_chk_warn, (void *__restrict __ptr, size_t __ptrlen, size_t __size, size_t __n, FILE *__restrict __stream), __fread_chk) __wur __warnattr ("fread called with bigger size * nmemb than length " "of destination buffer"); __fortify_function __wur size_t fread (void *__restrict __ptr, size_t __size, size_t __n, FILE *__restrict __stream) { if (__bos0 (__ptr) != (size_t) -1) { if (!__builtin_constant_p (__size) || !__builtin_constant_p (__n) || (__size | __n) >= (((size_t) 1) << (8 * sizeof (size_t) / 2))) return __fread_chk (__ptr, __bos0 (__ptr), __size, __n, __stream); if (__size * __n > __bos0 (__ptr)) return __fread_chk_warn (__ptr, __bos0 (__ptr), __size, __n, __stream); } return __fread_alias (__ptr, __size, __n, __stream); } Merging nodes for *__fread_chk. Candidates: *__fread_chk/98 (__fread_chk_warn) @0x7ffff6dc2b80 Type: function Visibility: undef external public next sharing asm name: 97 References: Referring: Read from file: /tmp/ccu88pge.o First run: 0 Function flags: Called by: test_surface/78 Calls: __fread_chk/97 (__fread_chk) @0x7ffff6dc2cf0 Type: function Visibility: external public previous sharing asm name: 98 References: Referring: Read from file: /tmp/ccu88pge.o First run: 0 Function flags: Called by: test_surface/78 (0.00 per call) After resolution: *__fread_chk/98 (__fread_chk_warn) @0x7ffff6dc2b80 Type: function Visibility: undef external public next sharing asm name: 97 References: Referring: Read from file: /tmp/ccu88pge.o First run: 0 Function flags: Called by: test_surface/78 Calls: __fread_chk/97 (__fread_chk) @0x7ffff6dc2cf0 Type: function Visibility: external public previous sharing asm name: 98 References: Referring: Read from file: /tmp/ccu88pge.o First run: 0 Function flags: Called by: test_surface/78 (0.00 per call) Calls: but we obviously shouldn't merge these ... (I believe we shouldn't drop any aliases at LTO symbol merging time, which means _not_ merging based on asm-name?)