Martin Sebor <mse...@gmail.com> writes: > Recent improvements to the strlen pass introduced the assumption > that when the length of a string has been recorded by the pass > the length is necessarily constant. Bug 83896 shows that this > assumption is not always true, and that GCC fails with an ICE > when it doesn't hold. To avoid the ICE the attached patch > removes the assumption. > > x86_64-linux bootstrap successful, regression test in progress. > > Martin > > PR tree-optimization/83896 - ice in get_string_len on a call to strlen with > non-constant length > > gcc/ChangeLog: > > PR tree-optimization/83896 > * tree-ssa-strlen.c (get_string_len): Avoid assuming length is constant. > > gcc/testsuite/ChangeLog: > > PR tree-optimization/83896 > * gcc.dg/strlenopt-43.c: New test. > > Index: gcc/tree-ssa-strlen.c > =================================================================== > --- gcc/tree-ssa-strlen.c (revision 256752) > +++ gcc/tree-ssa-strlen.c (working copy) > @@ -2772,7 +2772,9 @@ handle_pointer_plus (gimple_stmt_iterator *gsi) > } > } > > -/* Check if RHS is string_cst possibly wrapped by mem_ref. */ > +/* If RHS, either directly or indirectly, refers to a string of constant > + length, return it. Otherwise return a negative value. */ > + > static int > get_string_len (tree rhs) > {
I think this should be returning HOST_WIDE_INT given the unconstrained tree_to_shwi return. Same type change for rhslen in the caller. (Not my call, but it might be better to have a more specific function name, given that the file already had "get_string_length" before this function was added.) > @@ -2789,7 +2791,8 @@ get_string_len (tree rhs) > if (idx > 0) > { > strinfo *si = get_strinfo (idx); > - if (si && si->full_string_p) > + if (si && si->full_string_p > + && TREE_CODE (si->nonzero_chars) == INTEGER_CST) > return tree_to_shwi (si->nonzero_chars); tree_fits_shwi_p? Thanks, Richard > } > } > Index: gcc/testsuite/gcc.dg/strlenopt-43.c > =================================================================== > --- gcc/testsuite/gcc.dg/strlenopt-43.c (nonexistent) > +++ gcc/testsuite/gcc.dg/strlenopt-43.c (working copy) > @@ -0,0 +1,13 @@ > +/* PR tree-optimization/83896 - ice in get_string_len on a call to strlen > + with non-constant length > + { dg-do compile } > + { dg-options "-O2 -Wall" } */ > + > +extern char a[5]; > +extern char b[]; > + > +void f (void) > +{ > + if (__builtin_strlen (b) != 4) > + __builtin_memcpy (a, b, sizeof a); > +}