aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2006-03-11 14:52:57 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2006-03-11 14:52:57 +0000
commit9fb798d76ce4e7682e0aa1846275e8fb6f64f8cc (patch)
tree85ac110020df9a0d5ae2303c5c233d027bad4d3a /gcc
parent6dd3c0a5996256d8159c9c6be925114f692c398e (diff)
downloadgcc-9fb798d76ce4e7682e0aa1846275e8fb6f64f8cc.zip
gcc-9fb798d76ce4e7682e0aa1846275e8fb6f64f8cc.tar.gz
gcc-9fb798d76ce4e7682e0aa1846275e8fb6f64f8cc.tar.bz2
function.h (frame_offset_overflow): Declare.
* 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. From-SVN: r111964
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/cfgexpand.c3
-rw-r--r--gcc/function.c37
-rw-r--r--gcc/function.h5
4 files changed, 38 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b28931d..4d2e414 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 65ebdb7..75d8e9d 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 473f5d4..988d613 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 7c9ea3f..1b2484e 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);