https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92624
Bug ID: 92624 Summary: inconsistent folding of strcmp calls with unterminated arrays Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- This shows an inconsistency in how GCC handles code with undefined behavior that is easily detectable in all four functions below. But by "taking shortcuts" in some cases (and folding the result of the call when both arguments are known to point to the same array) while being more careful in others (even though the contents of the const arrays are known, they are also known not to be nul-terminated), it introduces an inconsistency in how the undefined behavior is handled: in the former case it's safely avoided while in the latter, by calling the library function, the result is unpredictable. At the same time, in the latter case the problem can be detected before expansion and diagnosed by -Wstringop-overflow (once pr88226 is resolved), in the former it won't be. This is one of the kinds of problems that will need to be dealt with if/when more consistency in dealing with undefined behavior is introduced (as has been discussed). $ cat t.c && gcc -O2 -S -Wall -Wextra -fdump-tree-optimized=/dev/stdout t.c const char a[] = { '1', '2' }; const char b[] = { '1', '2' }; int f0 (void) { const char *p = a, *q = b; return __builtin_strcmp (p, q); // not folded } int f1 (void) { const char *p = a, *q = a; return __builtin_strcmp (p, q); // folded to zero } int g0 (void) { const char *p = a, *q = b; return __builtin_strncmp (p, q, 4); // not folded } int g1 (void) { const char *p = a, *q = a; return __builtin_strncmp (p, q, 4); // folded to zero } ;; Function f0 (f0, funcdef_no=0, decl_uid=1932, cgraph_uid=1, symbol_order=2) f0 () { int _2; <bb 2> [local count: 1073741824]: _2 = __builtin_strcmp (&a, &b); [tail call] return _2; } ;; Function f1 (f1, funcdef_no=1, decl_uid=1937, cgraph_uid=2, symbol_order=3) f1 () { <bb 2> [local count: 1073741824]: return 0; } ;; Function g0 (g0, funcdef_no=2, decl_uid=1942, cgraph_uid=3, symbol_order=4) g0 () { int _2; <bb 2> [local count: 1073741824]: _2 = __builtin_strncmp (&a, &b, 4); [tail call] return _2; } ;; Function g1 (g1, funcdef_no=5, decl_uid=1947, cgraph_uid=4, symbol_order=5) g1 () { <bb 2> [local count: 1073741824]: return 0; }