https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67133

--- Comment #21 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Martin Jambor from comment #20)
> The problem is that when inlining transformation sets fndecl of the
> call statement, it does not set the fntype (of the statement). Then
> infer_nonnull_range_by_attribute comes along, looks only at the fntype
> and infers that the call has more attributes than it actually has.
> 
> The following (untested) patch avoids the ICE.  Even though this issue
> suggests that the type of fndecl and fntype have to be in sync, I have
> vague recollections that call statement's fntype was supposed to stick
> to the original type in the source somehow (though IIRC it is
> primarily used for indirect calls).  In other words, I am not sure the
> patch is 100% correct.  Honza, Richi, what are your opinions?

fntype is supposed to be the type specifying the "ABI", and yes it was
designed mainly to preserve indirect call behavior when we propagate
a (eventually "incompatible") fndecl to the call.

Iff IPA redirects a call to sth very different (like unreachable () here)
it doesn't make sense to preserve that detail.

OTOH users like infer_nonnull_range_by_attribute cannot rely on
gimple_call_fntype being "compatible" with the actual call (like in
terms of number of arguments).  So

         /* Now see if op appears in the nonnull list.  */
          for (tree t = TREE_VALUE (attrs); t; t = TREE_CHAIN (t))
            {
              int idx = TREE_INT_CST_LOW (TREE_VALUE (t)) - 1;
              tree arg = gimple_call_arg (stmt, idx);

lacks a check that idx < gimple_call_num_args.

I don't think the non-null attribute is at fault here.

> 
> diff --git a/gcc/cgraph.c b/gcc/cgraph.c
> index 22a9852..5e5b308 100644
> --- a/gcc/cgraph.c
> +++ b/gcc/cgraph.c
> @@ -1461,6 +1461,7 @@ cgraph_edge::redirect_call_stmt_to_callee (void)
>      {
>        new_stmt = e->call_stmt;
>        gimple_call_set_fndecl (new_stmt, e->callee->decl);
> +      gimple_call_set_fntype (new_stmt, TREE_TYPE (e->callee->decl));
>        update_stmt_fn (DECL_STRUCT_FUNCTION (e->caller->decl), new_stet);
>      }

Reply via email to