[Bug lto/51744] Erroneous warning: memset used with constant zero length parameter
rguenth at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Fri Mar 21 08:58:00 GMT 2014
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51744
--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
typedef __SIZE_TYPE__ size_t;
extern void *memset (void *__s, int __c, size_t __n) __attribute__
((__nothrow__)) __attribute__ ((__nonnull__ (1)));
extern void __warn_memset_zero_len (void) __attribute__((__warning__ ("memset
used with constant zero length parameter; this could be due to transposed
parameters")));
extern __inline __attribute__((__always_inline__))
__attribute__((__artificial__))
void * __attribute__ ((__nothrow__))
memset (void *__dest, int __ch, size_t __len)
{
if (__builtin_constant_p (__len) && __len == 0
&& (!__builtin_constant_p (__ch) || __ch != 0))
{
__warn_memset_zero_len ();
return __dest;
}
return __builtin___memset_chk (__dest, __ch, __len,
__builtin_object_size (__dest, 0));
}
void
main (int argc, char **argv)
{
char buf[5000];
memset (buf, 0xFF, argc);
}
This breaks a lot of applications if you build them with LTO and
-D_FORTIFY_SOURCE=2. The reason this happens is that when LTO bytecode
is output we still have
<bb 2>:
_2 = (long unsigned int) argc_1(D);
_6 = __builtin_constant_p (_2);
if (_6 != 0)
goto <bb 3>;
else
goto <bb 5>;
<bb 3>:
if (_2 == 0)
goto <bb 4>;
else
goto <bb 5>;
<bb 4>:
__warn_memset_zero_len ();
goto <bb 6>;
<bb 5>:
__memset_chk (&buf, 255, _2, 5000);
<bb 6>:
buf ={v} {CLOBBER};
thus __builtin_constant_p is not yet forced to be evaluated. This means that
we put __warn_memset_zero_len into the LTO symbol table which is queried
by the linker and this causes it to warn at the "beginning" of link-time.
Also (as can be seen with the cases where we introduce a call late) the
linker wants to see a final set of symbols at this time, thus it won't drop
the reference to __warn_memset_zero_len even if during LTRANS phase we
optimize it away.
More information about the Gcc-bugs
mailing list