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

--- Comment #23 from Martin Sebor <msebor at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #22)

Your question may have been rhetorical but to be explicit, the real difference
is hidden in the implementation (which is why these warnings can sometimes seem
inconsistent).  GCC doesn't warn for the second test case (copied below)
because it only considers the lower bound of len's range:

int a[2];
void foo (unsigned len)
{
  if (len == 1 || len == 20)
    __builtin_memset (a, 0, len);
}

But the warning would trigger if GCC decided it was profitable to split the
memset call into two statements:

int a[2];
void foo (unsigned len)
{
  if (len == 1)
    a[0] = 0;
  else if (len == 20)
    __builtin_memset (a, 0, 20);
}

I suspect most users (though not all, otherwise this report would have never
been raised) would consider a warning valid and helpful for the source code. 
But if instead of (len == 1 || len == 20) the condition were to be written in
terms of a relational expression (like len <= N) where N were greater than or
even equal to sizeof (a) + 1, I'd expect complaints about the warning being a
false positive because GCC can't "know" that len == N necessarily holds.

Reply via email to