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