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)

Reply via email to