diff options
author | Fritz Reese <fritzoreese@gmail.com> | 2016-07-17 20:13:41 +0000 |
---|---|---|
committer | Jerry DeLisle <jvdelisle@gcc.gnu.org> | 2016-07-17 20:13:41 +0000 |
commit | 43068916e3c8ce005cce382d24af4e75753cfabe (patch) | |
tree | 19a50866091bdb30b6a2a08e83748752362c9c93 /gcc/fortran/trans-decl.c | |
parent | 48b3613757c8959fc49165fdc9531b504fb8e30f (diff) | |
download | gcc-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.c | 40 |
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)) |