Martin Sebor <mse...@gmail.com> writes:
> In addition to assuming that built-in functions are called with
> the correct number of arguments (bug 83603), the restrict pass
> also assumes that they are called with arguments of the expected
> types.  When a built-in is declared with no prototype and called
> with arguments of the wrong type (such as memcpy (3, dst, ""))
> the pass crashes GCC with a SEGV.
>
> The attached patch prevents invalid calls from being checked for
> -Wrestrict violations.  It's meant to be applied in conjunction
> with the patch for bug 83603:
>    https://gcc.gnu.org/ml/gcc-patches/2018-01/msg00005.html
>
> A separate fix is to have GCC issue a warning for declarations
> of built-ins with no prototype.  I opened bug 83656 to track this
> change request to the C front end (C++ already warns for this).
>
> Another improvement is to also warn about calls with the wrong number
> or types of arguments when a built-in is declared without a prototype
> despite the first warning, similarly to what Clang does.  I opened
> bug 83657 to add this warning.
>
> Martin
>
> PR tree-optimization/83655 - ICE on an invalid call to memcpy declared with 
> no prototype
>
> gcc/testsuite/ChangeLog:
>
>       PR tree-optimization/83655
>       * gcc.dg/Wrestrict-5.c: New test.
>       * c-c++-common/builtins.c: New test.
>
> gcc/ChangeLog:
>
>       PR tree-optimization/83655
>       * gimple-ssa-warn-restrict.c (wrestrict_dom_walker::check_call): 
>
> diff --git a/gcc/gimple-ssa-warn-restrict.c b/gcc/gimple-ssa-warn-restrict.c
> index ac545e4..47d4900 100644
> --- a/gcc/gimple-ssa-warn-restrict.c
> +++ b/gcc/gimple-ssa-warn-restrict.c
> @@ -1688,7 +1688,17 @@ wrestrict_dom_walker::check_call (gcall *call)
>    if (!dstwr && strfun)
>      dstwr = size_one_node;
>  
> -  if (check_bounds_or_overlap (call, dst, src, dstwr, NULL_TREE))
> +  /* DST and SRC can be null for a call with an insufficient number
> +     of arguments to a built-in function declared without a protype.  */

Typo: prototype.

> +  if (!dst || !src)
> +    return;
> +
> +  /* DST, SRC, or DSTWR can also have the wrong type in a call to
> +     a function declared without a prototype.  Avoid checking such
> +     invalid calls.  */
> +  if (TREE_CODE (TREE_TYPE (dst)) != POINTER_TYPE
> +      || TREE_CODE (TREE_TYPE (src)) != POINTER_TYPE
> +      || (dstwr && !INTEGRAL_TYPE_P (TREE_TYPE (dstwr))))
>      return;

Isn't the canonical way of handling this kind of thing to use:

  if (!gimple_call_builtin_p (call, BUILT_IN_NORMAL)
    return;

instead of:

  tree func = gimple_call_fndecl (call);
  if (!func || DECL_BUILT_IN_CLASS (func) != BUILT_IN_NORMAL)
    return;

?  

Thanks,
Richard

Reply via email to