This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gfortran] Fix PR 20361: Check if equivalence fits on stack


We didn't check if an equivalence actually fits on the stack when building it,
so big equivalences caused segfaults.  This patch fixes it, fairly trivial,
the only change whose reason is non-obvious is that I'm now giving the union
an identifier.  This is required, because making the union TREE_STATIC gives
the compiler a reason to actually look at its name.

Bubblestrapped and regtested, I also verified that the assembly output
correctly changes for different values of -fmax-stack-var-size.  Is a testcase
which scans the assembler output preferred, or is a testcase which uses a huge
array enough?  Ok?

- Tobi

2005-03-12  Tobias Schl"uter  <tobias.schlueter@physik.uni-muenchen.de>

        PR fortran/20361
        * trans-array.c (gfc_stack_space_left): Remove unused variable.
        (gfc_can_put_var_on_stack): Move to trans-decl.c, remove #if 0'ed
	code.
        * trans-array.h (gfc_stack_space_left, gfc_can_put_var_on_stack):
        Remove declaration / prototype.
	* trans-common.c (build_equiv_decl): Give union a name.  Check if
	it can be put on the stack.
        * trans-decl.c (gfc_stack_space_left): Move function here.
        (gfc_build_qualified_array): Fix comment typo.
        * trans.h (gfc_put_var_on_stack): Add prototype.

Index: trans-array.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/trans-array.c,v
retrieving revision 1.39
diff -u -p -r1.39 trans-array.c
--- trans-array.c	24 Feb 2005 21:59:24 -0000	1.39
+++ trans-array.c	12 Mar 2005 14:55:11 -0000
@@ -99,43 +99,6 @@ static gfc_ss *gfc_walk_subexpr (gfc_ss 
 static gfc_ss gfc_ss_terminator_var;
 gfc_ss * const gfc_ss_terminator = &gfc_ss_terminator_var;
 
-unsigned HOST_WIDE_INT gfc_stack_space_left;
-
-
-/* Returns true if a variable of specified size should go on the stack.  */
-
-int
-gfc_can_put_var_on_stack (tree size)
-{
-  unsigned HOST_WIDE_INT low;
-
-  if (!INTEGER_CST_P (size))
-    return 0;
-
-  if (gfc_option.flag_max_stack_var_size < 0)
-    return 1;
-
-  if (TREE_INT_CST_HIGH (size) != 0)
-    return 0;
-
-  low = TREE_INT_CST_LOW (size);
-  if (low > (unsigned HOST_WIDE_INT) gfc_option.flag_max_stack_var_size)
-    return 0;
-
-/* TODO: Set a per-function stack size limit.  */
-#if 0
-  /* We should be a bit more clever with array temps.  */
-  if (gfc_option.flag_max_function_vars_size >= 0)
-    {
-      if (low > gfc_stack_space_left)
-	return 0;
-
-      gfc_stack_space_left -= low;
-    }
-#endif
-
-  return 1;
-}
 
 static tree
 gfc_array_dataptr_type (tree desc)
Index: trans-array.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/trans-array.h,v
retrieving revision 1.7
diff -u -p -r1.7 trans-array.h
--- trans-array.h	8 Nov 2004 14:56:40 -0000	1.7
+++ trans-array.h	12 Mar 2005 14:55:11 -0000
@@ -95,11 +95,6 @@ tree gfc_conv_array_stride (tree, int);
 tree gfc_conv_array_lbound (tree, int);
 tree gfc_conv_array_ubound (tree, int);
 
-/* The remaining space available for stack variables.  */
-extern unsigned HOST_WIDE_INT gfc_stack_space_left;
-/* Returns true if a variable of specified size should go on the stack.  */
-int gfc_can_put_var_on_stack (tree);
-
 /* Build expressions for accessing components of an array descriptor.  */
 tree gfc_conv_descriptor_data (tree);
 tree gfc_conv_descriptor_offset (tree);
Index: trans-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/trans-common.c,v
retrieving revision 1.23
diff -u -p -r1.23 trans-common.c
--- trans-common.c	23 Feb 2005 19:02:14 -0000	1.23
+++ trans-common.c	12 Mar 2005 14:55:11 -0000
@@ -260,10 +260,11 @@ build_equiv_decl (tree union_type, bool 
       return decl;
     }
 
-  decl = build_decl (VAR_DECL, NULL, union_type);
+  decl = build_decl (VAR_DECL, get_identifier ("equiv"), union_type);
   DECL_ARTIFICIAL (decl) = 1;
 
-  DECL_COMMON (decl) = 1;
+  if (!gfc_can_put_var_on_stack (DECL_SIZE_UNIT (decl)))
+      TREE_STATIC (decl) = 1;
 
   TREE_ADDRESSABLE (decl) = 1;
   TREE_USED (decl) = 1;
Index: trans-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/trans-decl.c,v
retrieving revision 1.54
diff -u -p -r1.54 trans-decl.c
--- trans-decl.c	24 Feb 2005 18:26:27 -0000	1.54
+++ trans-decl.c	12 Mar 2005 14:55:12 -0000
@@ -317,6 +317,32 @@ gfc_sym_mangled_function_id (gfc_symbol 
 }
 
 
+/* Returns true if a variable of specified size should go on the stack.  */
+
+int
+gfc_can_put_var_on_stack (tree size)
+{
+  unsigned HOST_WIDE_INT low;
+
+  if (!INTEGER_CST_P (size))
+    return 0;
+
+  if (gfc_option.flag_max_stack_var_size < 0)
+    return 1;
+
+  if (TREE_INT_CST_HIGH (size) != 0)
+    return 0;
+
+  low = TREE_INT_CST_LOW (size);
+  if (low > (unsigned HOST_WIDE_INT) gfc_option.flag_max_stack_var_size)
+    return 0;
+
+/* TODO: Set a per-function stack size limit.  */
+
+  return 1;
+}
+
+
 /* Finish processing of a declaration and install its initial value.  */
 
 static void
@@ -533,7 +559,7 @@ gfc_build_qualified_array (tree decl, gf
 
 
 /* For some dummy arguments we don't use the actual argument directly.
-   Instead we create a local decl and use that.  This allows us to preform
+   Instead we create a local decl and use that.  This allows us to perform
    initialization, and construct full type information.  */
 
 static tree
Index: trans.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/trans.h,v
retrieving revision 1.23
diff -u -p -r1.23 trans.h
--- trans.h	24 Feb 2005 21:59:24 -0000	1.23
+++ trans.h	12 Mar 2005 14:55:12 -0000
@@ -391,6 +391,9 @@ void gfc_shadow_sym (gfc_symbol *, tree,
 /* Restore the original variable.  */
 void gfc_restore_sym (gfc_symbol *, gfc_saved_var *);
 
+/* Returns true if a variable of specified size should go on the stack.  */
+int gfc_can_put_var_on_stack (tree);
+
 /* Allocate the lang-spcific part of a decl node.  */
 void gfc_allocate_lang_decl (tree);
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]