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

            Bug ID: 96758
           Summary: strncmp miscompiles as memcmp
           Product: gcc
           Version: 10.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: gcc-bugs at vgkmb dot com
  Target Milestone: ---

Created attachment 49106
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49106&action=edit
strncmp test program

strncmp(x, y, n) == 0 generates the wrong code under -O2 when:
- n is a constant power of two
- x is a non-constant buffer of size > n with runtime content
- y is "c ? a : b" where
- c is a non-constant condition
- and a and b are constant strings with lengths < n

Actual code: equivalent to memcmp(x, y, n) == 0 but is incorrect since neither
string is guaranteed to be at least n characters long.

Expected code: strncmp library call or inlined equivalent.

Host/target: x86_64-pc-linux-gnu
OS: Fedora 32 Linux 5.7.16-200.fc32.x86_64

Reduced from case found in smartmontools-7.1 compiled by the distro provided
compiler gcc (GCC) 10.2.1 20200723 (Red Hat 10.2.1-1).

#include <string.h>
#include <stdio.h>

int main(int argc, char *argv[]) {
    const char *s = argc > 0 ? "a" : "b";
    char x[5];
    char y[5] = "a\0a";
    memcpy(x, y, sizeof(y));
    printf("%d\n", !strncmp(x, s, 4));
    return 0;
}

Compiled as "gcc -O2 test.c" this prints "0" but should print "1" (and does
without -O2).

I confirmed via gcc.godbolt.org that it was OK in 9.3 but broken in 10 onward:
https://gcc.godbolt.org/z/e37fsP

I reproduced locally on the same system with latest main branch at 87c753ac
configured and built with defaults.

Then I bisected from tag releases/gcc-9.3.0 on and found the first bad commit
27c14dbc6b (SVN r277076) whose title seems related:

    PR tree-optimization/91996 - fold non-constant strlen relational
expressions

For the bisects I configured with --enable-languages=c --disable-multilib
--disable-bootstrap to speed up testing.

Please find attached preprocessed repro source for the case above. Expected
output is "1" (confirmed by compiling without -O2).

Reply via email to