https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77357
Bug ID: 77357 Summary: strlen of constant strings not folded 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: --- GCC successfully folds some simple calls to strlen with constant arguments but not others, both with and without optimization. The results with optimization are somewhat better but still not as good as they could be. Besides opening up other optimization opportunities, improving folding (even without optimization) will help detect more coding bugs (such as buffer overflows). The following test case shows that GCC folds global constant character arrays and constant pointers to string literals but it fails to do the same for static local const arrays or pointers or global aggregates. With optimization, it still fails to fold const aggregates and ends up calling strlen. $ cat xyz.c && /build/gcc-trunk-svn/gcc/xgcc -B /build/gcc-trunk-svn/gcc -O0 -S -Wall -Wextra -Wpedantic -fdump-tree-optimized=/dev/stdout strlen.c extern int vsprintf (char*, const char*, __builtin_va_list); void g (char *d, __builtin_va_list va) { const char f[] = "%i"; vsprintf (d, f, va); } void h (char *d, const char *f, __builtin_va_list va) { vsprintf (d, f, va); } ;; Function global_array (global_array, funcdef_no=0, decl_uid=1756, cgraph_uid=0, symbol_order=3) global_array () { <bb 2>: <bb 3>: return; } ;; Function global_pointer (global_pointer, funcdef_no=1, decl_uid=1759, cgraph_uid=1, symbol_order=4) global_pointer () { const char * s.0_1; long unsigned int _2; <bb 2>: s.0_1 = "abc"; _2 = 3; if (_2 != 3) goto <bb 3>; else goto <bb 4>; <bb 3>: __builtin_abort (); <bb 4>: return; } ;; Function local_array (local_array, funcdef_no=2, decl_uid=1762, cgraph_uid=2, symbol_order=5) local_array () { static const char a[4] = "abc"; long unsigned int _1; <bb 2>: _1 = __builtin_strlen (&a); if (_1 != 3) goto <bb 3>; else goto <bb 4>; <bb 3>: __builtin_abort (); <bb 4>: return; } ;; Function local_pointer (local_pointer, funcdef_no=3, decl_uid=1766, cgraph_uid=3, symbol_order=6) local_pointer () { const char * const s; long unsigned int _1; <bb 2>: s_2 = "abc"; _1 = __builtin_strlen (s_2); if (_1 != 3) goto <bb 3>; else goto <bb 4>; <bb 3>: __builtin_abort (); <bb 4>: return; } ;; Function global_struct (global_struct, funcdef_no=4, decl_uid=1770, cgraph_uid=4, symbol_order=7) global_struct () { long unsigned int _1; <bb 2>: _1 = __builtin_strlen (&x.a); if (_1 != 3) goto <bb 3>; else goto <bb 4>; <bb 3>: __builtin_abort (); <bb 4>: return; } ;; Function local_struct (local_struct, funcdef_no=5, decl_uid=1773, cgraph_uid=5, symbol_order=8) local_struct () { static const struct X x = {.a="abc"}; long unsigned int _1; <bb 2>: _1 = __builtin_strlen (&x.a); if (_1 != 3) goto <bb 3>; else goto <bb 4>; <bb 3>: __builtin_abort (); <bb 4>: return; }