aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-decl.c
diff options
context:
space:
mode:
authorFritz Reese <fritzoreese@gmail.com>2016-07-17 20:13:41 +0000
committerJerry DeLisle <jvdelisle@gcc.gnu.org>2016-07-17 20:13:41 +0000
commit43068916e3c8ce005cce382d24af4e75753cfabe (patch)
tree19a50866091bdb30b6a2a08e83748752362c9c93 /gcc/fortran/trans-decl.c
parent48b3613757c8959fc49165fdc9531b504fb8e30f (diff)
downloadgcc-43068916e3c8ce005cce382d24af4e75753cfabe.zip
gcc-43068916e3c8ce005cce382d24af4e75753cfabe.tar.gz
gcc-43068916e3c8ce005cce382d24af4e75753cfabe.tar.bz2
re PR fortran/71523 (Static variables given automatic initializers with -finit-* and -fmax-stack-var-size)
2016-07-17 Fritz Reese <fritzoreese@gmail.com> PR fortran/71523 * trans-decl.c (gfc_finish_var_decl): Replace automatic initializer with a static one. * gfortran.dg/pr71523_1.f90: New test. * gfortran.dg/pr71523_2.f90: New test. From-SVN: r238420
Diffstat (limited to 'gcc/fortran/trans-decl.c')
-rw-r--r--gcc/fortran/trans-decl.c40
1 files changed, 38 insertions, 2 deletions
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index f026bea..6c9bf50 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -657,7 +657,43 @@ gfc_finish_var_decl (tree decl, gfc_symbol * sym)
|| sym->attr.pointer
|| sym->attr.allocatable)
&& !DECL_ARTIFICIAL (decl))
- TREE_STATIC (decl) = 1;
+ {
+ TREE_STATIC (decl) = 1;
+
+ /* Because the size of this variable isn't known until now, we may have
+ greedily added an initializer to this variable (in build_init_assign)
+ even though the max-stack-var-size indicates the variable should be
+ static. Therefore we rip out the automatic initializer here and
+ replace it with a static one. */
+ gfc_symtree *st = gfc_find_symtree (sym->ns->sym_root, sym->name);
+ gfc_code *prev = NULL;
+ gfc_code *code = sym->ns->code;
+ while (code && code->op == EXEC_INIT_ASSIGN)
+ {
+ /* Look for an initializer meant for this symbol. */
+ if (code->expr1->symtree == st)
+ {
+ if (prev)
+ prev->next = code->next;
+ else
+ sym->ns->code = code->next;
+
+ break;
+ }
+
+ prev = code;
+ code = code->next;
+ }
+ if (code && code->op == EXEC_INIT_ASSIGN)
+ {
+ /* Keep the init expression for a static initializer. */
+ sym->value = code->expr2;
+ /* Cleanup the defunct code object, without freeing the init expr. */
+ code->expr2 = NULL;
+ gfc_free_statement (code);
+ free (code);
+ }
+ }
/* Handle threadprivate variables. */
if (sym->attr.threadprivate
@@ -1693,7 +1729,7 @@ gfc_get_symbol_decl (gfc_symbol * sym)
if (TREE_STATIC (decl)
&& !(sym->attr.use_assoc && !intrinsic_array_parameter)
&& (sym->attr.save || sym->ns->proc_name->attr.is_main_program
- || flag_max_stack_var_size == 0
+ || !gfc_can_put_var_on_stack (DECL_SIZE_UNIT (decl))
|| sym->attr.data || sym->ns->proc_name->attr.flavor == FL_MODULE)
&& (flag_coarray != GFC_FCOARRAY_LIB
|| !sym->attr.codimension || sym->attr.allocatable))