https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61294

Jason Merrill <jason at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|WAITING                     |NEW
                 CC|                            |jason at gcc dot gnu.org
          Component|c++                         |middle-end

--- Comment #4 from Jason Merrill <jason at gcc dot gnu.org> ---
It's clearly a false positive; the warning is intended to catch calls where the
user wrote a 0 directly in the argument list for memset (which suggests
accidentally transposed arguments), not cases where some execution path might
result in a 0 argument (which works fine).  The only question is what there is
to fix either in GCC or GLIBC to avoid this false positive.

A simple way to work around this is to guard the memset with if (npoints > 0).

The false positive seems to come up fairly often:

https://sourceware.org/ml/binutils/2012-02/msg00073.html
https://bugzilla.redhat.com/show_bug.cgi?id=452219
https://www.nsnam.org/bugzilla/show_bug.cgi?id=1165

Changing component to middle-end.

Reduced C testcase:

typedef __SIZE_TYPE__ size_t;
extern void *malloc (size_t __size) __attribute__ ((__malloc__)) __attribute__
((__warn_unused_result__));
extern void *memset (void *__s, int __c, size_t __n) __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 *
  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));
}

int i;
inline int f()
{
  if (i)
    return i;
  else
    return 0;
}

void g(unsigned char val)
{
  int len = f();
  void *p = malloc (len);
  memset (p, val, len);
}

Reply via email to