[Bug lto/51744] Erroneous warning: memset used with constant zero length parameter

2014-08-06 Thread amodra at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51744

Alan Modra amodra at gmail dot com changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 CC||amodra at gmail dot com
 Resolution|--- |FIXED

--- Comment #11 from Alan Modra amodra at gmail dot com ---
This has now been fixed on mainline binutils


[Bug lto/51744] Erroneous warning: memset used with constant zero length parameter

2014-03-24 Thread rguenth at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51744

--- Comment #6 from Richard Biener rguenth at gcc dot gnu.org ---
Btw, it works when using gold ...


[Bug lto/51744] Erroneous warning: memset used with constant zero length parameter

2014-03-24 Thread mark at infocomm dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51744

--- Comment #7 from Mark Pizzolato mark at infocomm dot com ---
Thanks for reducing this test case further.  That illuminates something for me:

Specifically:

Notice in the following lines:

  if (__builtin_constant_p (__len)  __len == 0
   (!__builtin_constant_p (__ch) || __ch != 0))
{

The part of the expression || __ch != 0)

What could possibly be the purpose of this check?

That is exactly why the 3rd condition I previously mentioned:

 3) memset is called with a NON zero fill value argument.

triggers this issue.  The warning is about the length, but it is checking the
value being set.  How could that make sense?  Clearly this check lets the vast
majority of uses of memset pass without issue since all of those cases use 0 as
the value to be set.

From my point of view, if that check wasn't there (i.e. remove || __ch != 0
from the expression), the problem would not exist.


[Bug lto/51744] Erroneous warning: memset used with constant zero length parameter

2014-03-24 Thread rguenth at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51744

--- Comment #8 from Richard Biener rguenth at gcc dot gnu.org ---
(In reply to Mark Pizzolato from comment #7)
 Thanks for reducing this test case further.  That illuminates something for
 me:
 
 Specifically:
 
 Notice in the following lines:
 
   if (__builtin_constant_p (__len)  __len == 0
(!__builtin_constant_p (__ch) || __ch != 0))
 {
 
 The part of the expression || __ch != 0)
 
 What could possibly be the purpose of this check?
 
 That is exactly why the 3rd condition I previously mentioned:
 
  3) memset is called with a NON zero fill value argument.
 
 triggers this issue.  The warning is about the length, but it is checking
 the value being set.  How could that make sense?  Clearly this check lets
 the vast majority of uses of memset pass without issue since all of those
 cases use 0 as the value to be set.
 
 From my point of view, if that check wasn't there (i.e. remove || __ch !=
 0 from the expression), the problem would not exist.

When val == 0 then the case of len == 0 is ambiguous and you can't really
tell the user they swapped val and len (because they are equal).


[Bug lto/51744] Erroneous warning: memset used with constant zero length parameter

2014-03-24 Thread mark at infocomm dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51744

--- Comment #9 from Mark Pizzolato mark at infocomm dot com ---
 When val == 0 then the case of len == 0 is ambiguous and you can't really
tell the user they swapped val and len (because they are equal).

That is certainly true.

I'm not sure how that specifically relates to the problem since the warning
message is only about the length being 0.

The problem is that the warning is being issued incorrectly when the set value
is != 0 and the length is not a constant.


[Bug lto/51744] Erroneous warning: memset used with constant zero length parameter

2014-03-24 Thread rguenth at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51744

--- Comment #10 from Richard Biener rguenth at gcc dot gnu.org ---
It's a GNU ld bug I believe.

https://sourceware.org/bugzilla/show_bug.cgi?id=16746


[Bug lto/51744] Erroneous warning: memset used with constant zero length parameter

2014-03-21 Thread rguenth at gcc dot gnu.org
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.


[Bug lto/51744] Erroneous warning: memset used with constant zero length parameter

2014-03-21 Thread rguenth at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51744

--- Comment #5 from Richard Biener rguenth at gcc dot gnu.org ---
It also (sadly) means this works with -fno-use-linker-plugin.  It also means
that not outputting the UNDEF into the LTO symbol table for this case doesn't
work as the executable will not link (we optimize the symbol away) if we don't
fold away the reference to it later.

I see no better way than either forcing the linker to re-scan needed symbols
and warn at a second stage only or to fold __builtin_constant_p earlier.


[Bug lto/51744] Erroneous warning: memset used with constant zero length parameter

2014-03-21 Thread rguenth at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51744

Richard Biener rguenth at gcc dot gnu.org changed:

   What|Removed |Added

  Known to fail||4.7.3, 4.8.3, 4.9.0
   Severity|normal  |major


[Bug lto/51744] Erroneous warning: memset used with constant zero length parameter

2012-10-23 Thread mark at infocomm dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51744



--- Comment #2 from Mark Pizzolato mark at infocomm dot com 2012-10-23 
16:42:06 UTC ---

Created attachment 28514

  -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=28514

MUCH simpler test case


[Bug lto/51744] Erroneous warning: memset used with constant zero length parameter

2012-10-23 Thread mark at infocomm dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51744



Mark Pizzolato mark at infocomm dot com changed:



   What|Removed |Added



 CC||mark at infocomm dot com



--- Comment #3 from Mark Pizzolato mark at infocomm dot com 2012-10-23 
16:43:01 UTC ---

This may be a bug in gcc OR the linker.  I don't know, BUT I have a more

precise description of the issue and a much simpler minimal test case.



The problem occurs when all of the following conditions are true:

1) gcc is invoked with -O2 and -flto

2) memset is called with a non-constant length argument

3) memset is called with a NON zero fill value argument.



The minimal test case is:



#include string.h



void

main (int argc, char **argv)

{

char buf[5000];



memset (buf, 0xFF, argc);

}



To conform to the bug submission guidelines, the preprocessed file for the this

test is attached.


[Bug lto/51744] Erroneous warning: memset used with constant zero length parameter

2012-01-04 Thread rguenth at gcc dot gnu.org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51744

Richard Guenther rguenth at gcc dot gnu.org changed:

   What|Removed |Added

   Keywords||diagnostic, lto
 Status|UNCONFIRMED |NEW
   Last reconfirmed||2012-01-04
 CC||hubicka at gcc dot gnu.org
 Ever Confirmed|0   |1

--- Comment #1 from Richard Guenther rguenth at gcc dot gnu.org 2012-01-04 
10:31:09 UTC ---
I think this is a linker bug, GCC optimizes away the function (seeing that
the argument is _not_ zero), but the linker warns about it anyway and it
is still output for some reason:

72: 004006f0 2 FUNCGLOBAL HIDDEN15
__warn_memset_zero_le
n

resolution file:

2
ma2.o 4
84 cd7721f0 PREVAILING_DEF_IRONLY ma_init
95 cd7721f0 PREVAILING_DEF_IRONLY ma_pool
105 cd7721f0 PREVAILING_DEF_IRONLY ma_get_cell
124 cd7721f0 RESOLVED_EXEC __warn_memset_zero_len
ma2_test.o 4
86 64da28d6 PREVAILING_DEF main
108 64da28d6 RESOLVED_IR ma_get_cell
113 64da28d6 RESOLVED_IR ma_pool
117 64da28d6 RESOLVED_IR ma_init