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

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |msebor at gcc dot gnu.org

--- Comment #2 from Martin Sebor <msebor at gcc dot gnu.org> ---
When the result of strncmp is only used to test for equality to zero that it
determines must evaluate to either true or false GCC 10 issues the
-Wstring-compare warning and folds those comparisons to the respective
constants (see the adjusted test case below).

But GCC doesn't issue the warning when the result is also used for other things
like in the test case.  I'm thinking it probably should warn regardless.

$ cat pr95673.c && gcc -O2 -S -Wall -Wextra -Wnull-dereference
-fdump-tree-optimized=/dev/stdout pr95673.c
typedef __SIZE_TYPE__ size_t;
typedef struct FILE FILE;
FILE* fmemopen (char*, size_t, const char*);
int fclose (FILE*);
void* memcpy (void*, const void*, size_t);
long fread (void*, size_t, size_t, FILE*);
int strncmp (const char*, const char*, size_t);
int printf (const char*, ...);

int main (void)
{
 char buffer[20] = {0};
 char data_read[sizeof("MAGIC")-1];

 memcpy(buffer, "MAGIC", sizeof("MAGIC"));
 FILE * fd = fmemopen(buffer, 20, "rb");

 if (!fd)
  return -1;


 int ret = 0;
 if ((ret = fread(&data_read, sizeof("MAGIC"), 1, fd)) != 1)
 {
  return -1;
 }

 int cmp = (int)strncmp(data_read, "MAGIC", sizeof("MAGIC"));
 printf("strcmp(%s, %s) == %d\n", data_read, "MAGIC", cmp != 0);
 if (cmp != 0)
 {
  printf("cmp value is: %d\n", cmp != 0);
  printf("This code should not be reached\n");
  return -2;
 }

 printf("Comparison is valid\n");

 fclose(fd);
 return 0;
}
pr95673.c: In function ‘main’:
pr95673.c:28:12: warning: ‘__builtin_strcmp’ of a string of length 5 and an
array of size 5 evaluates to nonzero [-Wstring-compare]
   28 |  int cmp = (int)strncmp(data_read, "MAGIC", sizeof("MAGIC"));
      |            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pr95673.c:29:2: note: in this expression
   29 |  printf("strcmp(%s, %s) == %d\n", data_read, "MAGIC", cmp != 0);
      |  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

;; Function main (main, funcdef_no=0, decl_uid=1955, cgraph_uid=1,
symbol_order=0) (executed once)

Removing basic block 7
Removing basic block 8
main ()
{
  int ret;
  struct FILE * fd;
  char data_read[5];
  char buffer[20];
  long int _1;
  int _4;

  <bb 2> [local count: 1073741823]:
  buffer = "\x00";
  memcpy (&buffer, "MAGIC", 6);
  fd_10 = fmemopen (&buffer, 20, "rb");
  if (fd_10 == 0B)
    goto <bb 3>; [0.91%]
  else
    goto <bb 4>; [99.09%]

  <bb 3> [local count: 52117088]:
  goto <bb 6>; [100.00%]

  <bb 4> [local count: 1063970775]:
  _1 = fread (&data_read, 6, 1, fd_10);
  ret_12 = (int) _1;
  if (ret_12 != 1)
    goto <bb 3>; [3.98%]
  else
    goto <bb 5>; [96.02%]

  <bb 5> [local count: 1021624735]:
  printf ("strcmp(%s, %s) == %d\n", &data_read, "MAGIC", 1);
  printf ("cmp value is: %d\n", 1);
  __builtin_puts (&"This code should not be reached"[0]);

  <bb 6> [local count: 1073741824]:
  # _4 = PHI <-2(5), -1(3)>
  buffer ={v} {CLOBBER};
  data_read ={v} {CLOBBER};
  return _4;

}

Reply via email to