https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78153
Bug ID: 78153 Summary: strlen return value can be assumed to be less than PTRDIFF_MAX Product: gcc Version: 7.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: --- Due to the limits of ptrdiff_t the size of no object can exceed that of PTRDIFF_MAX. As a result, the return value of any valid strlen call can be assumed to be less than PTRDIFF_MAX. This might open up some optimization opportunities down the line, such as that after conversion to a signed type of the same size the result is non-negative. The test case below shows that GCC currently doesn't take advantage of this assumption. $ cat b.c && /build/gcc-git/gcc/xgcc -B/build/gcc-git/gcc -O2 -S -Wall -Wextra -Wpedantic -fdump-tree-optimized=/dev/stdout b.c extern __SIZE_TYPE__ strlen (const char*); void f (const char *s) { if (__PTRDIFF_MAX__ <= strlen (s)) __builtin_abort (); } void g (const char *s) { __PTRDIFF_TYPE__ n = strlen (s); if (n < 0) __builtin_abort (); } ;; Function f (f, funcdef_no=0, decl_uid=1795, cgraph_uid=0, symbol_order=0) f (const char * s) { long unsigned int _1; <bb 2>: _1 = strlen (s_3(D)); if (_1 > 9223372036854775806) goto <bb 3>; else goto <bb 4>; <bb 3>: __builtin_abort (); <bb 4>: return; } ;; Function g (g, funcdef_no=1, decl_uid=1798, cgraph_uid=1, symbol_order=1) g (const char * s) { long int n; long unsigned int _1; <bb 2>: _1 = strlen (s_3(D)); n_4 = (long int) _1; if (n_4 < 0) goto <bb 3>; else goto <bb 4>; <bb 3>: __builtin_abort (); <bb 4>: return; }