This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix missing stack adjustment from expand_builtin_setjmp


expand_builtin_setjmp generates a jump around the code to be executed when the
return value is not 0, currently by directly calling emit_jump_insn without
properly flushing the pending stack adjustments.

This miscompiles the Ada testcase below on e.g. x86-linux when
accumulate_outgoing_args is forced to false and optimization turned on,
resulting in segmentation violation at run-time.

The following patch fixes this problem by using emit_jump instead of the
current sequence. 

Bootstrap and regression tests OK on mainline for all languages on
i686-pc-linux-gnu.

Olivier

--

2003-08-30  Olivier Hainque  <hainque@act-europe.fr>

	* builtins.c (expand_builtin_setjmp): Use emit_jump to jump around
	the != 0 case, which ensures pending stack adjustments are flushed.

*** builtins.c.ori	Thu Aug 21 16:16:56 2003
--- builtins.c	Thu Aug 21 16:20:27 2003
*************** expand_builtin_setjmp (arglist, target)
*** 603,612 ****
  
    expand_builtin_setjmp_setup (buf_addr, next_lab);
  
!   /* Set TARGET to zero and branch to the continue label.  */
    emit_move_insn (target, const0_rtx);
!   emit_jump_insn (gen_jump (cont_lab));
!   emit_barrier ();
    emit_label (next_lab);
  
    expand_builtin_setjmp_receiver (next_lab);
--- 603,613 ----
  
    expand_builtin_setjmp_setup (buf_addr, next_lab);
  
!   /* Set TARGET to zero and branch to the continue label.  Use emit_jump to
!      ensure that pending stack adjustments are flushed.  */
    emit_move_insn (target, const0_rtx);
!   emit_jump (cont_lab);
! 
    emit_label (next_lab);
  
    expand_builtin_setjmp_receiver (next_lab);

------------------------------------------------------------------------------
Testcase (bug-setjmp.ada):
--------------------------

package body S is

   function N_Sources return Natural is
   begin
      return 5;
   end;

end S;

package S is

   Max_Number_Of_Sources : constant Positive := 256;
   type Source_Range is  range 0 .. Max_Number_Of_Sources;

   function N_Sources return Natural;

end S;


with Ada.Finalization;

with S; use S;

package T is
      
   type Record_T is new Ada.Finalization.Controlled with null record;
   
   type Bitmap_T is array (1 .. N_Sources) of Boolean;
   
   type Report_T is record
      R : Record_T;
      M : Bitmap_T;
   end record;

end T;

ith Ada.Text_IO; use Ada.Text_IO;

with T; use T;

procedure P is
   procedure Dump (I : Integer) is
   begin
      Put_Line (Integer'Image (I));
   end;
      
   Not_Found : exception;
begin
   declare
      R : Report_T;
   begin
      Dump (R.M'Last);
      raise Not_Found;
   end;
exception
   when Not_Found => null;
end;

------------------------------------------------------------------------------
How to reproduce:
-----------------

$ gcc -dumpmachine 
i686-pc-linux-gnu

$ gcc -v
Configured with: [...] --disable-nls --enable-languages=all 
Thread model: posix
gcc version 3.4 20030814 (experimental)

$ gnatchop bug-setjmp.ada
$ gnatmake -O2 -mno-accumulate-outgoing-args p.adb

$ ./p
 5

raised PROGRAM_ERROR : stack overflow (or erroneous memory access)

--

After the patch, the expected behavior is observed:

$ ./p
 5
$


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]