https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83671
Martin Sebor <msebor at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |diagnostic Status|UNCONFIRMED |NEW Last reconfirmed| |2018-01-03 CC| |msebor at gcc dot gnu.org Component|c |tree-optimization Ever confirmed|0 |1 --- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> --- The reason for the warning is that the solution implemented for bug 83373 is not effective at -O1 because the strlen pass (where it's been added) doesn't run at that optimization level. Warnings like -Warray-bounds and -Wstringop-overflow rely on optimization, especially constant and range propagation. The latter doesn't run at -O1 either. The better the optimizer the higher the ratio of true positives to false negatives and false positives. The warning in this case is also independent of inlining and can be reproduced with the following simple test case: char dst[20]; char src[10]; void my_strcpy (void) { size_t len = strlen (src); if (len < sizeof src) memcpy (dst, src, len + 1); else { memcpy (dst, src, sizeof dst - 1); dst[sizeof dst - 1] = '\0'; } } The IL the -Wstringop-overflow warning works with can be seen in the dump of the -fdump-tree-optimized option (below). At -O1, the second memcpy call unconditionally accesses 19 bytes from the src array which triggers the warning. Because the strlen pass doesn't run, the warning has no way of telling that the strlen(src) call cannot return a value greater than 19. In this specific case it's possible to avoid the warning by moving the strlen(array) optimization to run even at -O1 which seems like a good idea regardless of the warning, so I'll confirm this bug on that basis. There will still be other cases where the full strlen pass is required and where these kinds of issues will not be avoidable. func2 () { size_t len; long unsigned int _4; <bb 2> [local count: 1073741825]: len_3 = strlen (&src); if (len_3 <= 19) goto <bb 3>; [50.00%] else goto <bb 4>; [50.00%] <bb 3> [local count: 536870912]: _4 = len_3 + 1; memcpy (&dest, &src, _4); goto <bb 5>; [100.00%] <bb 4> [local count: 536870912]: memcpy (&dest, &src, 19); MEM[(char *)&dest + 19B] = 0; <bb 5> [local count: 1073741825]: return; }