diff options
-rw-r--r-- | gcc/cgraphunit.c | 6 | ||||
-rw-r--r-- | gcc/function.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/thunk1.adb | 9 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/thunk1_pkg1.ads | 7 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/thunk1_pkg2.adb | 10 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/thunk1_pkg2.ads | 14 |
6 files changed, 52 insertions, 6 deletions
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 26d3995..bedb6e2 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -2171,7 +2171,10 @@ cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk) } } 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)) @@ -2184,6 +2187,7 @@ cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk) else { gimple_call_set_tail (call, true); + cfun->tail_call_marked = true; remove_edge (single_succ_edge (bb)); } diff --git a/gcc/function.c b/gcc/function.c index de59479..c4c9930 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -3322,13 +3322,15 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm, 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); diff --git a/gcc/testsuite/gnat.dg/thunk1.adb b/gcc/testsuite/gnat.dg/thunk1.adb new file mode 100644 index 0000000..278e023 --- /dev/null +++ b/gcc/testsuite/gnat.dg/thunk1.adb @@ -0,0 +1,9 @@ +-- { dg-do run } + +with Thunk1_Pkg1; use Thunk1_Pkg1; + +procedure Thunk1 is + D: Derived; +begin + D.Op ("Message"); +end; diff --git a/gcc/testsuite/gnat.dg/thunk1_pkg1.ads b/gcc/testsuite/gnat.dg/thunk1_pkg1.ads new file mode 100644 index 0000000..edb3eac --- /dev/null +++ b/gcc/testsuite/gnat.dg/thunk1_pkg1.ads @@ -0,0 +1,7 @@ +with Thunk1_Pkg2; use Thunk1_Pkg2; + +package Thunk1_Pkg1 is + + type Derived is new Ext with null record; + +end Thunk1_Pkg1; diff --git a/gcc/testsuite/gnat.dg/thunk1_pkg2.adb b/gcc/testsuite/gnat.dg/thunk1_pkg2.adb new file mode 100644 index 0000000..71ad45d --- /dev/null +++ b/gcc/testsuite/gnat.dg/thunk1_pkg2.adb @@ -0,0 +1,10 @@ +package body Thunk1_Pkg2 is + + procedure Op (This : in out Ext; S : String) is + begin + if S /= "Message" then + raise Program_Error; + end if; + end; + +end Thunk1_Pkg2; diff --git a/gcc/testsuite/gnat.dg/thunk1_pkg2.ads b/gcc/testsuite/gnat.dg/thunk1_pkg2.ads new file mode 100644 index 0000000..82a48d5 --- /dev/null +++ b/gcc/testsuite/gnat.dg/thunk1_pkg2.ads @@ -0,0 +1,14 @@ +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; |