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]

[PATCH] Fix broken code with huge frame


Hi,

The compiler silently emits brain-damaged code on x86 for the attached 
testcase:

_ada_test2:
.LFB4:
	pushl	%ebp
.LCFI0:
	movl	%esp, %ebp
.LCFI1:
	addl	$2147483640, %esp

It can't reasonably be compiled for 32-bit targets because the size of the 
frame overflows a signed 32-bit integer so the frame size computation wraps 
around in the target arithmetics.  The compiler already warns on PPC:

static void
rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12)
{
  rtx insn;
  rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
  rtx tmp_reg = gen_rtx_REG (Pmode, 0);
  rtx todec = gen_int_mode (-size, Pmode);

  if (INTVAL (todec) != -size)
    {
      warning (0, "stack frame too large");
      emit_insn (gen_trap ());
      return;



The proposed fix is to error out earlier in assign_stack_local_1:
test2.adb: In function 'Test2':
test2.adb:2: error: total size of local objects too large

Bootstrapped/regtested on x86_64-suse-linux.  OK for mainline?


2005-11-08  Eric Botcazou  <ebotcazou@adacore.com>

	* function.c (assign_stack_local_1): Issue an error message if
	the frame size overflows in the signed target arithmetics.


-- 
Eric Botcazou
with Set_G;
procedure Test2 is
  
  package Sets is new Set_G (Positive);

begin
   null;
end Test2;
generic
  type Universe is (<>); 
package Set_G is
  type SetArray is array (Universe) OF Boolean;
  type Set is record
    Store: SetArray := (others => False);
  end record;
  Phi: Set ;
end Set_G;
Index: function.c
===================================================================
--- function.c	(revision 106481)
+++ function.c	(working copy)
@@ -479,6 +479,19 @@ assign_stack_local_1 (enum machine_mode 
   function->x_stack_slot_list
     = gen_rtx_EXPR_LIST (VOIDmode, x, function->x_stack_slot_list);
 
+  /* Try to detect frame size overflows.  */
+  if ((FRAME_GROWS_DOWNWARD
+       ? (unsigned HOST_WIDE_INT) -function->x_frame_offset
+       : (unsigned HOST_WIDE_INT) function->x_frame_offset)
+	> ((unsigned HOST_WIDE_INT) 1 << (BITS_PER_WORD - 1))
+	    /* Leave room for the fixed part of the frame.  */
+	    - 64 * UNITS_PER_WORD)
+    {
+      error ("%Jtotal size of local objects too large", function->decl);
+      /* Avoid duplicate error messages as much as possible.  */
+      function->x_frame_offset = 0;
+    }
+
   return x;
 }
 

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