}
}
else
- gimple_call_set_tail (call, true);
+ {
+ gimple_call_set_tail (call, true);
+ cfun->tail_call_marked = true;
+ }
/* Build return value. */
if (!DECL_BY_REFERENCE (resdecl))
else
{
gimple_call_set_tail (call, true);
+ cfun->tail_call_marked = true;
remove_edge (single_succ_edge (bb));
}
else
emit_move_insn (parmreg, validated_mem);
- /* If we were passed a pointer but the actual value can safely live
- in a register, retrieve it and use it directly. */
+ /* If we were passed a pointer but the actual value can live in a register,
+ retrieve it and use it directly. Note that we cannot use nominal_mode,
+ because it will have been set to Pmode above, we must use the actual mode
+ of the parameter instead. */
if (data->arg.pass_by_reference && TYPE_MODE (TREE_TYPE (parm)) != BLKmode)
{
- /* We can't use nominal_mode, because it will have been set to
- Pmode above. We must use the actual mode of the parm. */
- if (use_register_for_decl (parm))
+ /* Use a stack slot for debugging purposes, except if a tail call is
+ involved because this would create a dangling reference. */
+ if (use_register_for_decl (parm) || cfun->tail_call_marked)
{
parmreg = gen_reg_rtx (TYPE_MODE (TREE_TYPE (parm)));
mark_user_reg (parmreg);
--- /dev/null
+package Thunk1_Pkg2 is
+
+ type Root is tagged record
+ I : Integer;
+ end record;
+
+ type Iface is interface;
+ procedure Op (This : in out Iface; S : String) is abstract;
+
+ type Ext is new Root and Iface with null record;
+
+ procedure Op (This : in out Ext; S : String);
+
+end Thunk1_Pkg2;