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.