From 26d04e5f6ba139e1bb67304415bd449fb3850aaf Mon Sep 17 00:00:00 2001
From: ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Sat, 11 Mar 2006 14:52:57 +0000
Subject: [PATCH] 	* function.h (frame_offset_overflow): Declare. 	*
 function.c (frame_offset_overflow): New function. 
 (assign_stack_local_1): Call it to detect that the offset overflows. 	*
 cfgexpand.c (alloc_stack_frame_space): Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@111964 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/ChangeLog   |  7 +++++++
 gcc/cfgexpand.c |  3 +++
 gcc/function.c  | 37 +++++++++++++++++++++++--------------
 gcc/function.h  |  5 +++++
 4 files changed, 38 insertions(+), 14 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b28931d7ad81..4d2e41435e2f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2006-03-11  Eric Botcazou  <ebotcazou@adacore.com>
+
+	* function.h (frame_offset_overflow): Declare.
+	* function.c (frame_offset_overflow): New function.
+	(assign_stack_local_1): Call it to detect that the offset overflows.
+	* cfgexpand.c (alloc_stack_frame_space): Likewise.
+
 2006-03-11  Steven Bosscher  <stevenb.gcc@gmail.com>
 
 	* config/sh/sh.c: Include alloc-pool.h.
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 65ebdb71fcc7..75d8e9d394b0 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -192,6 +192,9 @@ alloc_stack_frame_space (HOST_WIDE_INT size, HOST_WIDE_INT align)
     }
   frame_offset = new_frame_offset;
 
+  if (frame_offset_overflow (frame_offset, cfun->decl))
+    frame_offset = offset = 0;
+
   return offset;
 }
 
diff --git a/gcc/function.c b/gcc/function.c
index 473f5d4758fd..988d613c4d78 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -358,12 +358,33 @@ get_func_frame_size (struct function *f)
 /* Return size needed for stack frame based on slots so far allocated.
    This size counts from zero.  It is not rounded to PREFERRED_STACK_BOUNDARY;
    the caller may have to do that.  */
+
 HOST_WIDE_INT
 get_frame_size (void)
 {
   return get_func_frame_size (cfun);
 }
 
+/* Issue an error message and return TRUE if frame OFFSET overflows in
+   the signed target pointer arithmetics for function FUNC.  Otherwise
+   return FALSE.  */
+
+bool
+frame_offset_overflow (HOST_WIDE_INT offset, tree func)
+{  
+  unsigned HOST_WIDE_INT size = FRAME_GROWS_DOWNWARD ? -offset : offset;
+
+  if (size > ((unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (Pmode) - 1))
+	       /* Leave room for the fixed part of the frame.  */
+	       - 64 * UNITS_PER_WORD)
+    {
+      error ("%Jtotal size of local objects too large", func);
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
 /* Allocate a stack slot of SIZE bytes and return a MEM rtx for it
    with machine mode MODE.
 
@@ -479,20 +500,8 @@ assign_stack_local_1 (enum machine_mode mode, HOST_WIDE_INT size, int align,
   function->x_stack_slot_list
     = gen_rtx_EXPR_LIST (VOIDmode, x, function->x_stack_slot_list);
 
-  /* Try to detect frame size overflows on native platforms.  */
-#if BITS_PER_WORD >= 32
-  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;
-    }
-#endif
+  if (frame_offset_overflow (function->x_frame_offset, function->decl))
+    function->x_frame_offset = 0;
 
   return x;
 }
diff --git a/gcc/function.h b/gcc/function.h
index 7c9ea3f28619..1b2484e45224 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -534,6 +534,11 @@ extern void free_block_changes (void);
    the caller may have to do that.  */
 extern HOST_WIDE_INT get_frame_size (void);
 
+/* Issue an error message and return TRUE if frame OFFSET overflows in
+   the signed target pointer arithmetics for function FUNC.  Otherwise
+   return FALSE.  */
+extern bool frame_offset_overflow (HOST_WIDE_INT, tree);
+
 /* A pointer to a function to create target specific, per-function
    data structures.  */
 extern struct machine_function * (*init_machine_status) (void);
-- 
GitLab