]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR middle-end/20548 (ACATS c52103x c52104x c52104y segfault)
authorEric Botcazou <ebotcazou@adacore.com>
Sat, 16 Aug 2008 18:40:57 +0000 (18:40 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Sat, 16 Aug 2008 18:40:57 +0000 (18:40 +0000)
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

18 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/ada/ChangeLog
gcc/ada/gcc-interface/decl.c
gcc/ada/gcc-interface/utils2.c
gcc/calls.c
gcc/common.opt
gcc/doc/invoke.texi
gcc/doc/tm.texi
gcc/explow.c
gcc/expr.h
gcc/flags.h
gcc/function.c
gcc/gimplify.c
gcc/opts.c
gcc/reload1.c
gcc/stmt.c
gcc/toplev.c

index f7218cdd088da884411c9711913382ef3e1d0327..faa92264ee7cc20c84dcf974fe56062e64036de6 100644 (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 
index 8970d1bf6a3d6c36feb8b42de7f79858c52b424e..3c6318ee69415c3766d0807164c3bbce478a45fe 100644 (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 \
index 39f8cd17ae9ea7c8ced784e69d28f5cb39001cd8..14abbe489aceea738d7fb8d4d1d6acb2bf74e9ce 100644 (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
index a136f96bcc81a38e0a8d243158cb29dcaa3d3c48..65dd02e78349aaf9ce88923f0486d82e39c9a911 100644 (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,
index 0462426251f76935247bd293b0d6a5001109fa06..5077e640121f34e154d5ebd31970525a9a445977 100644 (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
     }
index 27aaaee6eff59da6f42044d5023a4cd556b38d89..3f3224455601a6eeeed93e1ffdaab2c8b811db53 100644 (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.  */
index 9b1972b8c4a62b6651843e971dc7e31176058d60..bad670903e3f0c1ff8783c14abe83e535515b1df 100644 (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
index 56a0bdadc55e9a92303b7b56743030b2317ebdc8..40c3df16594ea50715997416f6167559632673d7 100644 (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}
index 5decc331bd425e420bbc16d56bcfef423d6cd9b4..9b4a921883f402a3e8d7e648d2fd93dea3b01805 100644 (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
index 0c941d5b337badabbce911e3bc0b2dbec08d5df9..a1f76506023326ab6fcac8f4f04f7b2e578f4929 100644 (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)
index 39a51fcfe1334551a2da9d0fbad9d290f7761fda..29b1f3e931256b65279d1d836d40897d93c282c5 100644 (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
index cfd278f747eaa9cdc5d3634878570911fc578407..1de81f8e13b20d50b0b1061f1bc2aaff2c46093d 100644 (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.  */
 
index 98b8da0736567ccc6e275728854ee76a1da5ad1d..da26dc7d114ffb93113d3de111b002771e198c4c 100644 (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 ();
index 43c8df991fce732ed3484d6e732fa399344b29b3..b0b5e78968de23812ff3ef4e432d523a28fa2b77 100644 (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)
index 8dd8b8265fdf00df908f29d85ebbaef38bfe3184..7d582297eb6743ad8fcc2f0968521b465e70c623 100644 (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)
index 3abd6b24e33b2b7a3754313eea5faae55673250f..3ee0fc37cfa95e31e011fe1f53407dd7e3ec289f 100644 (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;
index 38d7b439aec0d3516d036072111aace03b784c07..f05cd0956fcd8f087cc7e4dec826bf7be1085a43 100644 (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;
-    }
 }
 \f
 /* Emit code to save the current value of stack.  */
index bb49a970b49b510f0622fc9bcf9cc0609fb898be..269086911c81759981e4a5315b154af960ecf0aa 100644 (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.  */