On Mon, Dec 18, 2023 at 9:35 AM Jakub Jelinek <ja...@redhat.com> wrote:
>
> Hi!
>
> The following testcase ICEs because we aren't careful enough with
> alloc_size attribute.  We do check that such an argument exists
> (although wouldn't handle correctly functions with more than INT_MAX
> arguments), but didn't check that it is scalar integer, the ICE is
> trying to fold_convert a structure to sizetype.
>
> Given that the attribute can also appear on non-prototyped functions
> where the arguments aren't known, I don't see how the FE could diagnose
> that and because we already handle the case where argument doesn't exist,
> I think we should also verify the argument is scalar integer convertible
> to sizetype.  Furthermore, given this is not just in diagnostics but
> used for code generation, I think it is better to punt on arguments with
> larger precision then sizetype, the upper bits are then truncated.
>
> The patch also fixes some formatting issues and avoids duplication of the
> fold_convert, plus removes unnecessary check for if (arg1 >= 0), that is
> always the case after if (arg1 < 0) return ...;
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Richard.

> 2023-12-18  Jakub Jelinek  <ja...@redhat.com>
>
>         PR tree-optimization/113013
>         * tree-object-size.cc (alloc_object_size): Return size_unknown if
>         corresponding argument(s) don't have integral type or have integral
>         type with higher precision than sizetype.  Don't check arg1 >= 0
>         uselessly.  Compare argument indexes against gimple_call_num_args
>         in unsigned type rather than int.  Formatting fixes.
>
>         * gcc.dg/pr113013.c: New test.
>
> --- gcc/tree-object-size.cc.jj  2023-11-02 07:49:20.538817331 +0100
> +++ gcc/tree-object-size.cc     2023-12-15 14:18:13.229417305 +0100
> @@ -794,21 +794,33 @@ alloc_object_size (const gcall *call, in
>          arg2 = TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN (p)))-1;
>      }
>    else if (gimple_call_builtin_p (call, BUILT_IN_NORMAL)
> -          && callfn && ALLOCA_FUNCTION_CODE_P (DECL_FUNCTION_CODE (callfn)))
> -  arg1 = 0;
> +          && callfn
> +          && ALLOCA_FUNCTION_CODE_P (DECL_FUNCTION_CODE (callfn)))
> +    arg1 = 0;
>
>    /* Non-const arguments are OK here, let the caller handle constness.  */
> -  if (arg1 < 0 || arg1 >= (int) gimple_call_num_args (call)
> -      || arg2 >= (int) gimple_call_num_args (call))
> +  if (arg1 < 0
> +      || (unsigned) arg1 >= gimple_call_num_args (call)
> +      || (arg2 >= 0 && (unsigned) arg2 >= gimple_call_num_args (call)))
>      return size_unknown (object_size_type);
>
> +  tree targ1 = gimple_call_arg (call, arg1);
> +  if (!INTEGRAL_TYPE_P (TREE_TYPE (targ1))
> +      || TYPE_PRECISION (TREE_TYPE (targ1)) > TYPE_PRECISION (sizetype))
> +    return size_unknown (object_size_type);
> +  targ1 = fold_convert (sizetype, targ1);
>    tree bytes = NULL_TREE;
>    if (arg2 >= 0)
> -    bytes = size_binop (MULT_EXPR,
> -       fold_convert (sizetype, gimple_call_arg (call, arg1)),
> -       fold_convert (sizetype, gimple_call_arg (call, arg2)));
> -  else if (arg1 >= 0)
> -    bytes = fold_convert (sizetype, gimple_call_arg (call, arg1));
> +    {
> +      tree targ2 = gimple_call_arg (call, arg2);
> +      if (!INTEGRAL_TYPE_P (TREE_TYPE (targ2))
> +         || TYPE_PRECISION (TREE_TYPE (targ2)) > TYPE_PRECISION (sizetype))
> +       return size_unknown (object_size_type);
> +      targ2 = fold_convert (sizetype, targ2);
> +      bytes = size_binop (MULT_EXPR, targ1, targ2);
> +    }
> +  else
> +    bytes = targ1;
>
>    return bytes ? bytes : size_unknown (object_size_type);
>  }
> --- gcc/testsuite/gcc.dg/pr113013.c.jj  2023-12-15 14:20:19.889631653 +0100
> +++ gcc/testsuite/gcc.dg/pr113013.c     2023-12-15 14:19:19.122488347 +0100
> @@ -0,0 +1,14 @@
> +/* PR tree-optimization/113013 */
> +/* { dg-do compile } */
> +/* { dg-options "-std=gnu99 -O2" } */
> +
> +struct S { short x; } s;
> +void *foo () __attribute__((__alloc_size__(1)));
> +struct S *p;
> +
> +__SIZE_TYPE__
> +bar (void)
> +{
> +  p = foo (s);
> +  return __builtin_dynamic_object_size (p, 0);
> +}
>
>         Jakub
>

Reply via email to