[Bug regression/95673] Inconsistent optimization behavior when there is a buffer overflow
msebor at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Mon Jun 15 21:44:19 GMT 2020
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;
}
More information about the Gcc-bugs
mailing list