On Mon, 12 Feb 2018, Jakub Jelinek wrote: > Hi! > > get_range_strlen fails to tell the caller that array_at_struct_end_p has > been involved in cases like (&ptr->arr[0]), while it handles > (ptr->arr). Fixed thusly, bootstrapped/regtested on x86_64-linux and > i686-linux, ok for trunk?
Ok. Richard. > 2018-02-12 Jakub Jelinek <ja...@redhat.com> > > PR tree-optimization/84339 > * gimple-fold.c (get_range_strlen): Set *FLEXP to true when handling > ARRAY_REF where first operand is array_at_struct_end_p COMPONENT_REF. > Formatting fixes. > > * gcc.c-torture/execute/pr84339.c: New test. > > --- gcc/gimple-fold.c.jj 2018-01-11 19:01:07.259442879 +0100 > +++ gcc/gimple-fold.c 2018-02-12 15:44:41.350214335 +0100 > @@ -1380,9 +1380,15 @@ get_range_strlen (tree arg, tree length[ > /* Set the minimum size to zero since the string in > the array could have zero length. */ > *minlen = ssize_int (0); > + > + if (TREE_CODE (TREE_OPERAND (arg, 0)) == COMPONENT_REF > + && type == TREE_TYPE (TREE_OPERAND (arg, 0)) > + && array_at_struct_end_p (TREE_OPERAND (arg, 0))) > + *flexp = true; > } > else if (TREE_CODE (arg) == COMPONENT_REF > - && TREE_CODE (TREE_TYPE (TREE_OPERAND (arg, 1))) == ARRAY_TYPE) > + && (TREE_CODE (TREE_TYPE (TREE_OPERAND (arg, 1))) > + == ARRAY_TYPE)) > { > /* Use the type of the member array to determine the upper > bound on the length of the array. This may be overly > @@ -1428,7 +1434,7 @@ get_range_strlen (tree arg, tree length[ > || integer_zerop (val)) > return false; > val = wide_int_to_tree (TREE_TYPE (val), > - wi::sub(wi::to_wide (val), 1)); > + wi::sub (wi::to_wide (val), 1)); > /* Set the minimum size to zero since the string in > the array could have zero length. */ > *minlen = ssize_int (0); > --- gcc/testsuite/gcc.c-torture/execute/pr84339.c.jj 2018-02-12 > 15:47:04.167243039 +0100 > +++ gcc/testsuite/gcc.c-torture/execute/pr84339.c 2018-02-12 > 15:46:48.363239868 +0100 > @@ -0,0 +1,30 @@ > +/* PR tree-optimization/84339 */ > + > +struct S { int a; char b[1]; }; > + > +__attribute__((noipa)) int > +foo (struct S *p) > +{ > + return __builtin_strlen (&p->b[0]); > +} > + > +__attribute__((noipa)) int > +bar (struct S *p) > +{ > + return __builtin_strlen (p->b); > +} > + > +int > +main () > +{ > + struct S *p = __builtin_malloc (sizeof (struct S) + 16); > + if (p) > + { > + p->a = 1; > + __builtin_strcpy (p->b, "abcdefg"); > + if (foo (p) != 7 || bar (p) != 7) > + __builtin_abort (); > + __builtin_free (p); > + } > + return 0; > +} > > Jakub > > -- Richard Biener <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)