re PR middle-end/20548 (ACATS c52103x c52104x c52104y segfault)

PR ada/20548
	* common.opt (-fstack-check): Do not declare the variable here.
	(-fstack-check=): New option variant.
	* doc/invoke.texi (Code Gen Options): Document it.
	* expr.h (STACK_OLD_CHECK_PROTECT): New macro.
	(STACK_CHECK_PROTECT): Bump to 3 pages if DWARF-2 EH is used.
	(STACK_CHECK_STATIC_BUILTIN): New macro.
	* doc/tm.texi (Stack Checking): Document STACK_CHECK_STATIC_BUILTIN.
	* opts.c: Include expr.h.
	(common_handle_option) <OPT_fold_stack_check_>: New case.
	<OPT_fstack_check>: Likewise.
	* calls.c (initialize_argument_information): Use TYPE_SIZE_UNIT
	consistently in the test for variable-sized types.  Adjust for
	new behaviour of flag_stack_check.
	* explow.c: Include except.h.
	(allocate_dynamic_stack_space): Do not take into account
	STACK_CHECK_MAX_FRAME_SIZE for static builtin stack checking.
	* function.c (gimplify_parameters): Use DECL_SIZE_UNIT in the test
	for variable-sized parameters.  Treat all parameters whose size is
	greater than STACK_CHECK_MAX_VAR_SIZE as variable-sized if generic
	stack checking is enabled.
	* gimplify.c (gimplify_decl_expr): Treat non-static objects whose
	size is greater than STACK_CHECK_MAX_VAR_SIZE as variable-sized
	if generic stack checking is enabled.
	(expand_function_end): Adjust for new behaviour of flag_stack_check.
	* reload1.c (reload): Likewise.
	* stmt.c (expand_decl): Assert that all automatic variables have
	fixed size at this point and remove dead code.
	* flags.h (stack_check_type): New enumeration type.
	(flag_stack_check): Declare.
	* toplev.c (flag_stack_check): New global variable.
	* Makefile.in (opts.o): Add dependency on EXPR_H.
	(explow.o): Add dependency on except.h.
ada/
	* gcc-interface/decl.c (gnat_to_gnu_entity): Use DECL_SIZE_UNIT in the
	setjmp test consistently.  Adjust for new behaviour of flag_stack_check.
	* gcc-interface/utils2.c (build_call_alloc_dealloc): Remove redundant
	test of flag_stack_check.  Adjust for new behaviour of flag_stack_check.

From-SVN: r139159
This commit is contained in:
Eric Botcazou 2008-08-16 18:40:57 +00:00 committed by Eric Botcazou
parent 6c397102b2
commit b38f3813f7
18 changed files with 233 additions and 95 deletions

View file

@ -1,3 +1,39 @@
2008-08-16 Eric Botcazou <ebotcazou@adacore.com>
PR ada/20548
* common.opt (-fstack-check): Do not declare the variable here.
(-fstack-check=): New option variant.
* doc/invoke.texi (Code Gen Options): Document it.
* expr.h (STACK_OLD_CHECK_PROTECT): New macro.
(STACK_CHECK_PROTECT): Bump to 3 pages if DWARF-2 EH is used.
(STACK_CHECK_STATIC_BUILTIN): New macro.
* doc/tm.texi (Stack Checking): Document STACK_CHECK_STATIC_BUILTIN.
* opts.c: Include expr.h.
(common_handle_option) <OPT_fold_stack_check_>: New case.
<OPT_fstack_check>: Likewise.
* calls.c (initialize_argument_information): Use TYPE_SIZE_UNIT
consistently in the test for variable-sized types. Adjust for
new behaviour of flag_stack_check.
* explow.c: Include except.h.
(allocate_dynamic_stack_space): Do not take into account
STACK_CHECK_MAX_FRAME_SIZE for static builtin stack checking.
* function.c (gimplify_parameters): Use DECL_SIZE_UNIT in the test
for variable-sized parameters. Treat all parameters whose size is
greater than STACK_CHECK_MAX_VAR_SIZE as variable-sized if generic
stack checking is enabled.
* gimplify.c (gimplify_decl_expr): Treat non-static objects whose
size is greater than STACK_CHECK_MAX_VAR_SIZE as variable-sized
if generic stack checking is enabled.
(expand_function_end): Adjust for new behaviour of flag_stack_check.
* reload1.c (reload): Likewise.
* stmt.c (expand_decl): Assert that all automatic variables have
fixed size at this point and remove dead code.
* flags.h (stack_check_type): New enumeration type.
(flag_stack_check): Declare.
* toplev.c (flag_stack_check): New global variable.
* Makefile.in (opts.o): Add dependency on EXPR_H.
(explow.o): Add dependency on except.h.
2008-08-16 Andy Hutchinson <hutchinsonandy@aim.com>
* config/avr/avr.c (avr_override_options): Reduce value of

View file

@ -2392,7 +2392,7 @@ diagnostic.o : diagnostic.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) version.h $(TM_P_H) $(FLAGS_H) $(INPUT_H) $(TOPLEV_H) intl.h \
$(DIAGNOSTIC_H) langhooks.h $(LANGHOOKS_DEF_H) diagnostic.def opts.h
opts.o : opts.c opts.h options.h $(TOPLEV_H) $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TREE_H) $(TM_H) langhooks.h $(GGC_H) $(RTL_H) \
coretypes.h $(TREE_H) $(TM_H) langhooks.h $(GGC_H) $(EXPR_H) $(RTL_H) \
output.h $(DIAGNOSTIC_H) $(TM_P_H) $(INSN_ATTR_H) intl.h $(TARGET_H) \
$(FLAGS_H) $(PARAMS_H) tree-pass.h $(DBGCNT_H) debug.h varray.h
opts-common.o : opts-common.c opts.h $(CONFIG_H) $(SYSTEM_H) \
@ -2495,7 +2495,7 @@ expmed.o : expmed.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_
$(TOPLEV_H) $(TM_P_H) langhooks.h $(DF_H) $(TARGET_H)
explow.o : explow.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
$(FLAGS_H) hard-reg-set.h insn-config.h $(EXPR_H) $(OPTABS_H) $(RECOG_H) \
$(TOPLEV_H) $(FUNCTION_H) $(GGC_H) $(TM_P_H) langhooks.h gt-explow.h \
$(TOPLEV_H) except.h $(FUNCTION_H) $(GGC_H) $(TM_P_H) langhooks.h gt-explow.h \
$(TARGET_H) output.h
optabs.o : optabs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(FLAGS_H) insn-config.h $(EXPR_H) $(OPTABS_H) libfuncs.h \

View file

@ -1,3 +1,11 @@
2008-08-16 Eric Botcazou <ebotcazou@adacore.com>
PR ada/20548
* gcc-interface/decl.c (gnat_to_gnu_entity): Use DECL_SIZE_UNIT in the
setjmp test consistently. Adjust for new behaviour of flag_stack_check.
* gcc-interface/utils2.c (build_call_alloc_dealloc): Remove redundant
test of flag_stack_check. Adjust for new behaviour of flag_stack_check.
2008-08-13 Samuel Tardieu <sam@rfc1149.net>
PR ada/36777

View file

@ -1303,12 +1303,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
}
}
if (definition && DECL_SIZE (gnu_decl)
if (definition && DECL_SIZE_UNIT (gnu_decl)
&& get_block_jmpbuf_decl ()
&& (TREE_CODE (DECL_SIZE (gnu_decl)) != INTEGER_CST
|| (flag_stack_check && !STACK_CHECK_BUILTIN
&& 0 < compare_tree_int (DECL_SIZE_UNIT (gnu_decl),
STACK_CHECK_MAX_VAR_SIZE))))
&& (TREE_CODE (DECL_SIZE_UNIT (gnu_decl)) != INTEGER_CST
|| (flag_stack_check == GENERIC_STACK_CHECK
&& compare_tree_int (DECL_SIZE_UNIT (gnu_decl),
STACK_CHECK_MAX_VAR_SIZE) > 0)))
add_stmt_with_node (build_call_1_expr
(update_setjmp_buf_decl,
build_unary_op (ADDR_EXPR, NULL_TREE,

View file

@ -1920,11 +1920,11 @@ build_call_alloc_dealloc (tree gnu_obj, tree gnu_size, unsigned align,
/* ??? For now, disable variable-sized allocators in the stack since
we can't yet gimplify an ALLOCATE_EXPR. */
else if (gnat_pool == -1
&& TREE_CODE (gnu_size) == INTEGER_CST && !flag_stack_check)
&& TREE_CODE (gnu_size) == INTEGER_CST
&& flag_stack_check != GENERIC_STACK_CHECK)
{
/* If the size is a constant, we can put it in the fixed portion of
the stack frame to avoid the need to adjust the stack pointer. */
if (TREE_CODE (gnu_size) == INTEGER_CST && !flag_stack_check)
{
tree gnu_range
= build_range_type (NULL_TREE, size_one_node, gnu_size);
@ -1937,9 +1937,8 @@ build_call_alloc_dealloc (tree gnu_obj, tree gnu_size, unsigned align,
return convert (ptr_void_type_node,
build_unary_op (ADDR_EXPR, NULL_TREE, gnu_decl));
}
else
gcc_unreachable ();
#if 0
else
return build2 (ALLOCATE_EXPR, ptr_void_type_node, gnu_size, gnu_align);
#endif
}

View file

@ -1069,10 +1069,10 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
rtx copy;
if (!COMPLETE_TYPE_P (type)
|| TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
|| (flag_stack_check && ! STACK_CHECK_BUILTIN
&& (0 < compare_tree_int (TYPE_SIZE_UNIT (type),
STACK_CHECK_MAX_VAR_SIZE))))
|| TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST
|| (flag_stack_check == GENERIC_STACK_CHECK
&& compare_tree_int (TYPE_SIZE_UNIT (type),
STACK_CHECK_MAX_VAR_SIZE) > 0))
{
/* This is a variable-sized object. Make space on the stack
for it. */

View file

@ -992,11 +992,13 @@ fvariable-expansion-in-unroller
Common Report Var(flag_variable_expansion_in_unroller) Optimization
Apply variable expansion when loops are unrolled
; Emit code to probe the stack, to help detect stack overflow; also
; may cause large objects to be allocated dynamically.
fstack-check=
Common Report RejectNegative Joined
-fstack-check=[no|generic|specific] Insert stack checking code into the program
fstack-check
Common Report Var(flag_stack_check)
Insert stack checking code into the program
Common Report
Insert stack checking code into the program. Same as -fstack-check=specific
fstack-limit
Common

View file

@ -15207,8 +15207,34 @@ a single-threaded environment since stack overflow is automatically
detected on nearly all systems if there is only one stack.
Note that this switch does not actually cause checking to be done; the
operating system must do that. The switch causes generation of code
to ensure that the operating system sees the stack being extended.
operating system or the language runtime must do that. The switch causes
generation of code to ensure that they see the stack being extended.
You can additionally specify a string parameter: @code{no} means no
checking, @code{generic} means force the use of old-style checking,
@code{specific} means use the best checking method and is equivalent
to bare @option{-fstack-check}.
Old-style checking is a generic mechanism that requires no specific
target support in the compiler but comes with the following drawbacks:
@enumerate
@item
Modified allocation strategy for large objects: they will always be
allocated dynamically if their size exceeds a fixed threshold.
@item
Fixed limit on the size of the static frame of functions: when it is
topped by a particular function, stack checking is not reliable and
a warning is issued by the compiler.
@item
Inefficiency: because of both the modified allocation strategy and the
generic implementation, the performances of the code are hampered.
@end enumerate
Note that old-style stack checking is also the fallback method for
@code{specific} if no target support has been added in the compiler.
@item -fstack-limit-register=@var{reg}
@itemx -fstack-limit-symbol=@var{sym}

View file

@ -3376,38 +3376,49 @@ linkage is necessary. The default is @code{0}.
@node Stack Checking
@subsection Specifying How Stack Checking is Done
GCC will check that stack references are within the boundaries of
the stack, if the @option{-fstack-check} is specified, in one of three ways:
GCC will check that stack references are within the boundaries of the
stack, if the option @option{-fstack-check} is specified, in one of
three ways:
@enumerate
@item
If the value of the @code{STACK_CHECK_BUILTIN} macro is nonzero, GCC
will assume that you have arranged for stack checking to be done at
appropriate places in the configuration files, e.g., in
@code{TARGET_ASM_FUNCTION_PROLOGUE}. GCC will do not other special
processing.
will assume that you have arranged for full stack checking to be done
at appropriate places in the configuration files. GCC will not do
other special processing.
@item
If @code{STACK_CHECK_BUILTIN} is zero and you defined a named pattern
called @code{check_stack} in your @file{md} file, GCC will call that
pattern with one argument which is the address to compare the stack
value against. You must arrange for this pattern to report an error if
the stack pointer is out of range.
If @code{STACK_CHECK_BUILTIN} is zero and the value of the
@code{STACK_CHECK_STATIC_BUILTIN} macro is nonzero, GCC will assume
that you have arranged for static stack checking (checking of the
static stack frame of functions) to be done at appropriate places
in the configuration files. GCC will only emit code to do dynamic
stack checking (checking on dynamic stack allocations) using the third
approach below.
@item
If neither of the above are true, GCC will generate code to periodically
``probe'' the stack pointer using the values of the macros defined below.
@end enumerate
Normally, you will use the default values of these macros, so GCC
will use the third approach.
If neither STACK_CHECK_BUILTIN nor STACK_CHECK_STATIC_BUILTIN is defined,
GCC will change its allocation strategy for large objects if the option
@option{-fstack-check} is specified: they will always be allocated
dynamically if their size exceeds @code{STACK_CHECK_MAX_VAR_SIZE} bytes.
@defmac STACK_CHECK_BUILTIN
A nonzero value if stack checking is done by the configuration files in a
machine-dependent manner. You should define this macro if stack checking
is require by the ABI of your machine or if you would like to have to stack
checking in some more efficient way than GCC's portable approach.
The default value of this macro is zero.
is require by the ABI of your machine or if you would like to do stack
checking in some more efficient way than the generic approach. The default
value of this macro is zero.
@end defmac
@defmac STACK_CHECK_STATIC_BUILTIN
A nonzero value if static stack checking is done by the configuration files
in a machine-dependent manner. You should define this macro if you would
like to do static stack checking in some more efficient way than the generic
approach. The default value of this macro is zero.
@end defmac
@defmac STACK_CHECK_PROBE_INTERVAL
@ -3418,7 +3429,7 @@ default value of 4096 is suitable for most systems.
@end defmac
@defmac STACK_CHECK_PROBE_LOAD
A integer which is nonzero if GCC should perform the stack probe
An integer which is nonzero if GCC should perform the stack probe
as a load instruction and zero if GCC should use a store instruction.
The default is zero, which is the most efficient choice on most systems.
@end defmac
@ -3429,6 +3440,10 @@ for languages where such a recovery is supported. The default value of
75 words should be adequate for most machines.
@end defmac
The following macros are relevant only if neither STACK_CHECK_BUILTIN
nor STACK_CHECK_STATIC_BUILTIN is defined; you can omit them altogether
in the opposite case.
@defmac STACK_CHECK_MAX_FRAME_SIZE
The maximum size of a stack frame, in bytes. GCC will generate probe
instructions in non-leaf functions to ensure at least this many bytes of

View file

@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h"
#include "tm_p.h"
#include "flags.h"
#include "except.h"
#include "function.h"
#include "expr.h"
#include "optabs.h"
@ -1190,10 +1191,13 @@ allocate_dynamic_stack_space (rtx size, rtx target, int known_align)
gcc_assert (!(stack_pointer_delta
% (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT)));
/* If needed, check that we have the required amount of stack. Take into
account what has already been checked. */
if (flag_stack_check && ! STACK_CHECK_BUILTIN)
probe_stack_range (STACK_CHECK_MAX_FRAME_SIZE + STACK_CHECK_PROTECT, size);
/* If needed, check that we have the required amount of stack.
Take into account what has already been checked. */
if (flag_stack_check == GENERIC_STACK_CHECK)
probe_stack_range (STACK_OLD_CHECK_PROTECT + STACK_CHECK_MAX_FRAME_SIZE,
size);
else if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK)
probe_stack_range (STACK_CHECK_PROTECT, size);
/* Don't use a TARGET that isn't a pseudo or is the wrong mode. */
if (target == 0 || !REG_P (target)

View file

@ -208,10 +208,16 @@ do { \
/* Provide default values for the macros controlling stack checking. */
/* The default is neither full builtin stack checking... */
#ifndef STACK_CHECK_BUILTIN
#define STACK_CHECK_BUILTIN 0
#endif
/* ...nor static builtin stack checking. */
#ifndef STACK_CHECK_STATIC_BUILTIN
#define STACK_CHECK_STATIC_BUILTIN 0
#endif
/* The default interval is one page. */
#ifndef STACK_CHECK_PROBE_INTERVAL
#define STACK_CHECK_PROBE_INTERVAL 4096
@ -222,9 +228,24 @@ do { \
#define STACK_CHECK_PROBE_LOAD 0
#endif
/* This value is arbitrary, but should be sufficient for most machines. */
/* This is a kludge to try to capture the discrepancy between the old
mechanism (generic stack checking) and the new mechanism (static
builtin stack checking). STACK_CHECK_PROTECT needs to be bumped
for the latter because part of the protection area is effectively
included in STACK_CHECK_MAX_FRAME_SIZE for the former. */
#ifdef STACK_CHECK_PROTECT
#define STACK_OLD_CHECK_PROTECT STACK_CHECK_PROTECT
#else
#define STACK_OLD_CHECK_PROTECT \
(USING_SJLJ_EXCEPTIONS ? 75 * UNITS_PER_WORD : 8 * 1024)
#endif
/* Minimum amount of stack required to recover from an anticipated stack
overflow detection. The default value conveys an estimate of the amount
of stack required to propagate an exception. */
#ifndef STACK_CHECK_PROTECT
#define STACK_CHECK_PROTECT (75 * UNITS_PER_WORD)
#define STACK_CHECK_PROTECT \
(USING_SJLJ_EXCEPTIONS ? 75 * UNITS_PER_WORD : 12 * 1024)
#endif
/* Make the maximum frame size be the largest we can and still only need

View file

@ -254,6 +254,27 @@ extern int flag_var_tracking;
warning message in case flag was set by -fprofile-{generate,use}. */
extern bool flag_speculative_prefetching_set;
/* Type of stack check. */
enum stack_check_type
{
/* Do not check the stack. */
NO_STACK_CHECK = 0,
/* Check the stack generically, i.e. assume no specific support
from the target configuration files. */
GENERIC_STACK_CHECK,
/* Check the stack and rely on the target configuration files to
check the static frame of functions, i.e. use the generic
mechanism only for dynamic stack allocations. */
STATIC_BUILTIN_STACK_CHECK,
/* Check the stack and entirely rely on the target configuration
files, i.e. do not use the generic mechanism at all. */
FULL_BUILTIN_STACK_CHECK
};
extern enum stack_check_type flag_stack_check;
/* Returns TRUE if generated code should match ABI version N or
greater is in use. */

View file

@ -3236,7 +3236,7 @@ gimplify_parameters (void)
walk_tree_without_duplicates (&data.passed_type,
gimplify_parm_type, &stmts);
if (!TREE_CONSTANT (DECL_SIZE (parm)))
if (TREE_CODE (DECL_SIZE_UNIT (parm)) != INTEGER_CST)
{
gimplify_one_sizepos (&DECL_SIZE (parm), &stmts);
gimplify_one_sizepos (&DECL_SIZE_UNIT (parm), &stmts);
@ -3250,9 +3250,12 @@ gimplify_parameters (void)
{
tree local, t;
/* For constant sized objects, this is trivial; for
/* For constant-sized objects, this is trivial; for
variable-sized objects, we have to play games. */
if (TREE_CONSTANT (DECL_SIZE (parm)))
if (TREE_CODE (DECL_SIZE_UNIT (parm)) == INTEGER_CST
&& !(flag_stack_check == GENERIC_STACK_CHECK
&& compare_tree_int (DECL_SIZE_UNIT (parm),
STACK_CHECK_MAX_VAR_SIZE) > 0))
{
local = create_tmp_var (type, get_name (parm));
DECL_IGNORED_P (local) = 0;
@ -4480,10 +4483,10 @@ expand_function_end (void)
if (arg_pointer_save_area && ! crtl->arg_pointer_save_area_init)
get_arg_pointer_save_area ();
/* If we are doing stack checking and this function makes calls,
/* If we are doing generic stack checking and this function makes calls,
do a stack probe at the start of the function to ensure we have enough
space for another stack frame. */
if (flag_stack_check && ! STACK_CHECK_BUILTIN)
if (flag_stack_check == GENERIC_STACK_CHECK)
{
rtx insn, seq;
@ -4491,7 +4494,7 @@ expand_function_end (void)
if (CALL_P (insn))
{
start_sequence ();
probe_stack_range (STACK_CHECK_PROTECT,
probe_stack_range (STACK_OLD_CHECK_PROTECT,
GEN_INT (STACK_CHECK_MAX_FRAME_SIZE));
seq = get_insns ();
end_sequence ();

View file

@ -1447,7 +1447,11 @@ gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p)
{
tree init = DECL_INITIAL (decl);
if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
if (TREE_CODE (DECL_SIZE_UNIT (decl)) != INTEGER_CST
|| (!TREE_STATIC (decl)
&& flag_stack_check == GENERIC_STACK_CHECK
&& compare_tree_int (DECL_SIZE_UNIT (decl),
STACK_CHECK_MAX_VAR_SIZE) > 0))
gimplify_vla_decl (decl, seq_p);
if (init && init != error_mark_node)

View file

@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see
#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "expr.h"
#include "ggc.h"
#include "output.h"
#include "langhooks.h"
@ -1900,6 +1901,37 @@ common_handle_option (size_t scode, const char *arg, int value,
flag_sched_stalled_insns_dep = value;
break;
case OPT_fstack_check_:
if (!strcmp (arg, "no"))
flag_stack_check = NO_STACK_CHECK;
else if (!strcmp (arg, "generic"))
/* This is the old stack checking method. */
flag_stack_check = STACK_CHECK_BUILTIN
? FULL_BUILTIN_STACK_CHECK
: GENERIC_STACK_CHECK;
else if (!strcmp (arg, "specific"))
/* This is the new stack checking method. */
flag_stack_check = STACK_CHECK_BUILTIN
? FULL_BUILTIN_STACK_CHECK
: STACK_CHECK_STATIC_BUILTIN
? STATIC_BUILTIN_STACK_CHECK
: GENERIC_STACK_CHECK;
else
warning (0, "unknown stack check parameter \"%s\"", arg);
break;
case OPT_fstack_check:
/* This is the same as the "specific" mode above. */
if (value)
flag_stack_check = STACK_CHECK_BUILTIN
? FULL_BUILTIN_STACK_CHECK
: STACK_CHECK_STATIC_BUILTIN
? STATIC_BUILTIN_STACK_CHECK
: GENERIC_STACK_CHECK;
else
flag_stack_check = NO_STACK_CHECK;
break;
case OPT_fstack_limit:
/* The real switch is -fno-stack-limit. */
if (value)

View file

@ -1301,9 +1301,9 @@ reload (rtx first, int global)
}
}
/* If we are doing stack checking, give a warning if this function's
frame size is larger than we expect. */
if (flag_stack_check && ! STACK_CHECK_BUILTIN)
/* If we are doing generic stack checking, give a warning if this
function's frame size is larger than we expect. */
if (flag_stack_check == GENERIC_STACK_CHECK)
{
HOST_WIDE_INT size = get_frame_size () + STACK_CHECK_FIXED_FRAME_SIZE;
static int verbose_warned = 0;

View file

@ -1867,8 +1867,8 @@ expand_decl (tree decl)
SET_DECL_RTL (decl, gen_rtx_MEM (BLKmode, const0_rtx));
else if (DECL_SIZE (decl) == 0)
/* Variable with incomplete type. */
{
/* Variable with incomplete type. */
rtx x;
if (DECL_INITIAL (decl) == 0)
/* Error message was already done; now avoid a crash. */
@ -1899,16 +1899,15 @@ expand_decl (tree decl)
TYPE_ALIGN (TREE_TYPE (TREE_TYPE (decl))));
}
else if (TREE_CODE (DECL_SIZE_UNIT (decl)) == INTEGER_CST
&& ! (flag_stack_check && ! STACK_CHECK_BUILTIN
&& 0 < compare_tree_int (DECL_SIZE_UNIT (decl),
STACK_CHECK_MAX_VAR_SIZE)))
else
{
/* Variable of fixed size that goes on the stack. */
rtx oldaddr = 0;
rtx addr;
rtx x;
/* Variable-sized decls are dealt with in the gimplifier. */
gcc_assert (TREE_CODE (DECL_SIZE_UNIT (decl)) == INTEGER_CST);
/* If we previously made RTL for this decl, it must be an array
whose size was determined by the initializer.
The old address was a register; set that register now
@ -1936,41 +1935,6 @@ expand_decl (tree decl)
emit_move_insn (oldaddr, addr);
}
}
else
/* Dynamic-size object: must push space on the stack. */
{
rtx address, size, x;
/* Record the stack pointer on entry to block, if have
not already done so. */
do_pending_stack_adjust ();
/* Compute the variable's size, in bytes. This will expand any
needed SAVE_EXPRs for the first time. */
size = expand_normal (DECL_SIZE_UNIT (decl));
free_temp_slots ();
/* Allocate space on the stack for the variable. Note that
DECL_ALIGN says how the variable is to be aligned and we
cannot use it to conclude anything about the alignment of
the size. */
address = allocate_dynamic_stack_space (size, NULL_RTX,
TYPE_ALIGN (TREE_TYPE (decl)));
/* Reference the variable indirect through that rtx. */
x = gen_rtx_MEM (DECL_MODE (decl), address);
set_mem_attributes (x, decl, 1);
SET_DECL_RTL (decl, x);
/* Indicate the alignment we actually gave this variable. */
#ifdef STACK_BOUNDARY
DECL_ALIGN (decl) = STACK_BOUNDARY;
#else
DECL_ALIGN (decl) = BIGGEST_ALIGNMENT;
#endif
DECL_USER_ALIGN (decl) = 0;
}
}
/* Emit code to save the current value of stack. */

View file

@ -306,6 +306,9 @@ rtx stack_limit_rtx;
to optimize, debug_info_level and debug_hooks in process_options (). */
int flag_var_tracking = AUTODETECT_VALUE;
/* Type of stack check. */
enum stack_check_type flag_stack_check = NO_STACK_CHECK;
/* True if the user has tagged the function with the 'section'
attribute. */