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

--- Comment #7 from Martin Sebor <msebor at gcc dot gnu.org> ---
The following is a more straightforward test case that's also miscompiled to
return zero:

  int main ()
  { 
    char a[] = "\0abc";

    return __builtin_memcmp (a, "\0\0\0\0", 4);
  }

main:
.LFB0:
        .cfi_startproc
        xorl    %eax, %eax
        ret

There seems to a series of mistakes that led to this bug.  First, in the
original test case, the initializer for the const float array of all zeros is
just a single null byte, regardless of how big the array is.  c_getstr()
returns the empty string for such an array and sets *STRLEN to 1.  As I
mentioned in comment #4, this is very confusing given that the function can be
called for non-strings and that the comment suggests embedded nuls are
reflected in the STRLEN result.

The c_getstr() caller that ultimately interprets this result wrong is
inline_expand_builtin_string_cmp() in builtins.c.  The comment above the
function  reads:

/* Inline expansion a call to str(n)cmp, with result going to
   TARGET if that's convenient.
   If the call is not been inlined, return NULL_RTX.  */

but it's (also) called from expand_builtin_memcmp(), so yet again, the comment
is incorrect or at best misleading.  The function then implements the correct
behavior for strncmp() but not for memcmp().  The miscompilation was apparently
introduced by r272993, most likely because of the misleading function name. 
The call to inline_expand_builtin_string_cmp() from expand_builtin_memcmp() was
introduced in r262636.

Reply via email to