From 43068916e3c8ce005cce382d24af4e75753cfabe Mon Sep 17 00:00:00 2001 From: Fritz Reese Date: Sun, 17 Jul 2016 20:13:41 +0000 Subject: [PATCH] re PR fortran/71523 (Static variables given automatic initializers with -finit-* and -fmax-stack-var-size) 2016-07-17 Fritz Reese 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 --- gcc/fortran/ChangeLog | 6 ++++ gcc/fortran/trans-decl.c | 40 +++++++++++++++++++++++-- gcc/testsuite/ChangeLog | 6 ++++ gcc/testsuite/gfortran.dg/pr71523_1.f90 | 22 ++++++++++++++ gcc/testsuite/gfortran.dg/pr71523_2.f90 | 38 +++++++++++++++++++++++ 5 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/pr71523_1.f90 create mode 100644 gcc/testsuite/gfortran.dg/pr71523_2.f90 diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 82e90da0236..04335d92726 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,9 @@ +2016-07-17 Fritz Reese + + PR fortran/71523 + * trans-decl.c (gfc_finish_var_decl): Replace automatic initializer with + a static one. + 2016-07-15 Jerry DeLisle Marco Restelli diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index f026bea5d86..6c9bf50a69a 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)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8de4e955db2..9568baa7e74 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2016-07-17 Fritz Reese + + PR fortran/71523 + * gfortran.dg/pr71523_1.f90: New test. + * gfortran.dg/pr71523_2.f90: New test. + 2016-07-16 Andreas Schwab * g++.dg/cpp0x/nullptr35.C (caught): Fix typo. diff --git a/gcc/testsuite/gfortran.dg/pr71523_1.f90 b/gcc/testsuite/gfortran.dg/pr71523_1.f90 new file mode 100644 index 00000000000..7b5b2abc88b --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr71523_1.f90 @@ -0,0 +1,22 @@ +! PR Fortran/71523 +! +! { dg-do compile } +! { dg-options "-fdump-tree-original -finit-local-zero -fautomatic -fmax-stack-var-size=8" } +! +! Make sure that variables larger than max-stack-var-size which become +! static are not given automatic initializers on function entry. +! + +function set(idx, val) + implicit none + integer, intent(in) :: idx, val + integer set + integer arr(100) + + set = arr(idx) + arr(idx) = val + return +end function + +! There should be no automatic initializer for arr +! { dg-final { scan-tree-dump-times "arr = " 0 "original" } } diff --git a/gcc/testsuite/gfortran.dg/pr71523_2.f90 b/gcc/testsuite/gfortran.dg/pr71523_2.f90 new file mode 100644 index 00000000000..5be0dd79881 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr71523_2.f90 @@ -0,0 +1,38 @@ +! PR Fortran/71523 +! +! { dg-do run } +! { dg-options "-finit-integer=12345 -fautomatic -fmax-stack-var-size=8" } +! +! Make sure that variables larger than max-stack-var-size become +! static and are given the correct _static_ initializer. +! + +function set(idx, val) + implicit none + integer, intent(in) :: idx, val + integer set + integer arr(100) + + set = arr(idx) + arr(idx) = val + return +end function + + integer set, val + + val = set(1, 5) + if (val .ne. 12345) then + call abort() + endif + + val = set(1, 10) + if (val .ne. 5) then + call abort() + endif + + val = set(1, 100) + if (val .ne. 10) then + call abort() + endif + +end