Don't allow sibcalls on nested functions

Richard Kenner kenner@vlsi1.ultra.nyu.edu
Mon Apr 21 21:11:00 GMT 2003


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@act-europe.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.  */



More information about the Gcc-patches mailing list