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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |rguenth at gcc dot gnu.org

--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> ---
  /* If this is not a builtin function, the function type through which the
     call is made may be different from the type of the function.  */
  if (!builtin_p)
    CALL_EXPR_FN (exp)
      = fold_convert (build_pointer_type (gimple_call_fntype (stmt)),
                      CALL_EXPR_FN (exp));

is probably one issue.  Maybe we should do

  builtin_p = gimple_call_builtin_p (stmt);

instead of

  builtin_p = decl && fndecl_built_in_p (decl);

where we fail to verify the function signature against that of the builtin.

Note that even with unconditionally converting we ICE, so expand_assignment
goes wrong at some point, not expecting the integer return type.  It does
so in expand_expr_real_1:

        tree fndecl = get_callee_fndecl (exp), attr;
..
        /* Check for a built-in function.  */
        if (fndecl && fndecl_built_in_p (fndecl))
          {
            gcc_assert (DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_FRONTEND);
            return expand_builtin (exp, target, subtarget, tmode, ignore);

where we then eventually get into the "verification" builtin expansion
does.  It only checks we have a REAL_TYPE as argument (not whether it is
of the correct mode).  And it doesn't check the return type.

In get_callee_fndecl STRIP_NOPS strips the conversion of the function type
as useless because the pointer types have the same mode.

Reply via email to