This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Don't allow sibcalls on nested functions
- From: kenner at vlsi1 dot ultra dot nyu dot edu (Richard Kenner)
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 21 Apr 03 17:15:48 EDT
- Subject: Don't allow sibcalls on nested functions
This can't be allowed because of the reason in the comment below.
I've asked Olivier to check whether this can happen in the case of a
pointer to the nested function, since that would be harder to fix.
The Ada test case is below. Tested on i686-pc-linux-gnu.
package body Histograms is
procedure Display (Zoom_Factor : Integer; Histogram : Histogram_T) is
procedure Check_Zoom_Factor is
begin
if Zoom_Factor /= Static_Zoom_Factor then
raise Program_Error;
end if;
end;
procedure Wrapper_For_Check_Zoom_Factor (Dummy : Natural) is
procedure Dumb is
I : Integer := Dummy;
begin
null;
end;
begin
Check_Zoom_Factor;
end;
begin
Wrapper_For_Check_Zoom_Factor (Histogram.N_Values);
end Display;
end Histograms;
package Histograms is
Static_Zoom_Factor : constant := 12;
type Histogram_T is record
N_Values : Natural;
end record;
procedure Display (Zoom_Factor : Integer; Histogram : Histogram_T);
end Histograms;
with Histograms; use Histograms;
procedure P is
Local_Histogram : Histogram_T := (N_Values => 55);
begin
Display (Static_Zoom_Factor, Local_Histogram);
end;
Thu Nov 28 09:06:21 2002 Olivier Hainque <hainque at act-europe dot fr>
* calls.c (expand_call): Prevent sibcall optimization for calls to
nested subprograms.
*** gcc/calls.c 19 Apr 2003 11:57:59 -0000 1.268
--- gcc/calls.c 19 Apr 2003 12:08:10 -0000
*************** expand_call (exp, target, ignore)
*** 2516,2519 ****
--- 2516,2523 ----
|| (flags & (ECF_RETURNS_TWICE | ECF_LONGJMP | ECF_NORETURN))
|| TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (addr)))
+ /* If the called function is nested in the current one, it might access
+ some of the caller's arguments, but could clobber them beforehand if
+ the argument areas are shared. */
+ || (fndecl && decl_function_context (fndecl) == current_function_decl)
/* If this function requires more stack slots than the current
function, we cannot change it into a sibling call. */