https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90766
Bug ID: 90766 Summary: strlen(a + i) missing range for arrays of unknown bound with strings of known length and variable i Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- GCC manages to fold the first two conditionals involving strlen but not the third, even though it has all the information to do that. The maybe_set_strlen_range() function in tree-ssa-strlen.c doesn't take the known length of the string stored in b into consideration. $ cat a.c && gcc -O2 -S -Wall -Wextra -Wpedantic -fdump-tree-optimized=/dev/stdout a.c const char s[] = "123"; void f (int i) { if (__builtin_strlen (&s[i]) > 3) // folded to false, good __builtin_abort (); } extern char a[8]; void g (int i) { __builtin_strcpy (a, "123"); if (__builtin_strlen (&s[i]) > 3) // folded to false, good __builtin_abort (); } extern char b[]; void h (int i) { __builtin_strcpy (b, "123"); if (__builtin_strlen (&b[i]) > 3) // not folded but could be __builtin_abort (); } ;; Function f (f, funcdef_no=0, decl_uid=1907, cgraph_uid=1, symbol_order=1) f (int i) { <bb 2> [local count: 1073741824]: return; } ;; Function g (g, funcdef_no=1, decl_uid=1911, cgraph_uid=2, symbol_order=2) g (int i) { <bb 2> [local count: 1073741824]: __builtin_memcpy (&a, "123", 4); [tail call] return; } ;; Function h (h, funcdef_no=2, decl_uid=1915, cgraph_uid=3, symbol_order=3) h (int i) { char * _1; long unsigned int _2; sizetype _7; <bb 2> [local count: 1073741824]: __builtin_memcpy (&b, "123", 4); _7 = (sizetype) i_5(D); _1 = &b + _7; _2 = __builtin_strlen (_1); if (_2 > 3) goto <bb 3>; [0.00%] else goto <bb 4>; [100.00%] <bb 3> [count: 0]: __builtin_abort (); <bb 4> [local count: 1073741824]: return; }