[PATCH] Fix ccp_fold_builtin (PR middle-end/38360)

Richard Guenther richard.guenther@gmail.com
Tue Dec 2 10:45:00 GMT 2008


On Tue, Dec 2, 2008 at 11:24 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> When the various builtin folders have been changed to accept the individual
> arguments rather than a CALL from which the number of arguments could be
> checked as well, it is caller's responsibility to check the number of
> arguments.  fold_call_expr/fold_builtin_n does that by separating the
> folders into fold_builtin_{0,1,2,3} etc., so for wrong number of arguments
> folding isn't attempted.  But in ccp_fold_builtin only a few calls have
> been changed to verify the number of arguments first, before accessing
> the individual gimple_call_arg arguments.  In 4.4 we ICE because
> gimple_call_arg checks that the argument number isn't greater or equal
> to nargs, in 4.3 we ICEd because CALL_EXPR_ARG reads some random value from
> memory after the call arguments (if it happened to be valid tree or NULL,
> it likely wouldn't be validated by validate_arg, but if it is random
> garbage, it can segfault).
> I've been able to reproduce this only with fputs and fputs_unlocked
> (supposedly because the compiler doesn't have builtin FILE type and so
> needs to be forgiving), for other calls trying to call them with
> wrong number of arguments when not prototyped resulted in errors,
> but I think it is safer to check it always.
>
> Bootstrapped/regtested on x86_64-linux, ok for trunk?

IMHO we should rather verify the number of arguments to the calls
and error out, see c-common.c:check_builtin_function_arguments.

Richard.

> 2008-12-02  Jakub Jelinek  <jakub@redhat.com>
>
>        PR middle-end/38360
>        * tree-ssa-ccp.c (ccp_fold_builtin): Bail out if the builtin doesn't
>        have the right number of arguments.
>
>        * gcc.c-torture/compile/pr38360.c: New test.
>
> --- gcc/tree-ssa-ccp.c.jj       2008-11-10 10:28:26.000000000 +0100
> +++ gcc/tree-ssa-ccp.c  2008-12-02 09:06:08.000000000 +0100
> @@ -2517,6 +2517,9 @@ ccp_fold_builtin (gimple stmt)
>       return NULL_TREE;
>     }
>
> +  if (arg_idx >= nargs)
> +    return NULL_TREE;
> +
>   /* Try to use the dataflow information gathered by the CCP process.  */
>   visited = BITMAP_ALLOC (NULL);
>   bitmap_clear (visited);
> @@ -2532,7 +2535,7 @@ ccp_fold_builtin (gimple stmt)
>   switch (DECL_FUNCTION_CODE (callee))
>     {
>     case BUILT_IN_STRLEN:
> -      if (val[0])
> +      if (val[0] && nargs == 1)
>        {
>          tree new_val =
>               fold_convert (TREE_TYPE (gimple_call_lhs (stmt)), val[0]);
> @@ -2564,22 +2567,24 @@ ccp_fold_builtin (gimple stmt)
>       break;
>
>     case BUILT_IN_FPUTS:
> -      result = fold_builtin_fputs (gimple_call_arg (stmt, 0),
> -                                   gimple_call_arg (stmt, 1),
> -                                  ignore, false, val[0]);
> +      if (nargs == 2)
> +       result = fold_builtin_fputs (gimple_call_arg (stmt, 0),
> +                                    gimple_call_arg (stmt, 1),
> +                                    ignore, false, val[0]);
>       break;
>
>     case BUILT_IN_FPUTS_UNLOCKED:
> -      result = fold_builtin_fputs (gimple_call_arg (stmt, 0),
> -                                  gimple_call_arg (stmt, 1),
> -                                   ignore, true, val[0]);
> +      if (nargs == 2)
> +       result = fold_builtin_fputs (gimple_call_arg (stmt, 0),
> +                                    gimple_call_arg (stmt, 1),
> +                                    ignore, true, val[0]);
>       break;
>
>     case BUILT_IN_MEMCPY_CHK:
>     case BUILT_IN_MEMPCPY_CHK:
>     case BUILT_IN_MEMMOVE_CHK:
>     case BUILT_IN_MEMSET_CHK:
> -      if (val[2] && is_gimple_val (val[2]))
> +      if (val[2] && is_gimple_val (val[2]) && nargs == 4)
>        result = fold_builtin_memory_chk (callee,
>                                           gimple_call_arg (stmt, 0),
>                                           gimple_call_arg (stmt, 1),
> @@ -2591,7 +2596,7 @@ ccp_fold_builtin (gimple stmt)
>
>     case BUILT_IN_STRCPY_CHK:
>     case BUILT_IN_STPCPY_CHK:
> -      if (val[1] && is_gimple_val (val[1]))
> +      if (val[1] && is_gimple_val (val[1]) && nargs == 3)
>        result = fold_builtin_stxcpy_chk (callee,
>                                           gimple_call_arg (stmt, 0),
>                                           gimple_call_arg (stmt, 1),
> @@ -2601,7 +2606,7 @@ ccp_fold_builtin (gimple stmt)
>       break;
>
>     case BUILT_IN_STRNCPY_CHK:
> -      if (val[2] && is_gimple_val (val[2]))
> +      if (val[2] && is_gimple_val (val[2]) && nargs == 4)
>        result = fold_builtin_strncpy_chk (gimple_call_arg (stmt, 0),
>                                            gimple_call_arg (stmt, 1),
>                                            gimple_call_arg (stmt, 2),
> --- gcc/testsuite/gcc.c-torture/compile/pr38360.c.jj    2008-12-02 09:08:46.000000000 +0100
> +++ gcc/testsuite/gcc.c-torture/compile/pr38360.c       2008-12-02 09:08:24.000000000 +0100
> @@ -0,0 +1,9 @@
> +/* PR middle-end/38360 */
> +
> +int
> +main ()
> +{
> +  fputs ("");
> +  fputs_unlocked ("");
> +  return 0;
> +}
>
>        Jakub
>



More information about the Gcc-patches mailing list