Message ID | 20180212214923.GJ5867@tucnak |
---|---|
State | New |
Headers | show |
Series | Fix get_range_strlen (PR tree-optimization/84339) | expand |
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 <jakub@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 > >
--- 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; +}