re PR fortran/71523 (Static variables given automatic initializers with -finit-*...
authorFritz Reese <fritzoreese@gmail.com>
Sun, 17 Jul 2016 20:13:41 +0000 (20:13 +0000)
committerJerry DeLisle <jvdelisle@gcc.gnu.org>
Sun, 17 Jul 2016 20:13:41 +0000 (20:13 +0000)
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

gcc/fortran/ChangeLog
gcc/fortran/trans-decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/pr71523_1.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/pr71523_2.f90 [new file with mode: 0644]

index 82e90da0236eadae4e750ef213c6f77b278a0b57..04335d927266e8cd41e6f663bb67fdb5aa68b788 100644 (file)
@@ -1,3 +1,9 @@
+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.
+
 2016-07-15  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
            Marco Restelli <mrestelli@gmail.com>
 
index f026bea5d866ee45fbd8b2849dccfd50d08f17b6..6c9bf50a69aa7b4993f0238df8583c72106fd713 100644 (file)
@@ -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))
index 8de4e955db2a701b40d97ebde972b2b799fa6efe..9568baa7e74ad4db03979041aec051bf3eeab472 100644 (file)
@@ -1,3 +1,9 @@
+2016-07-17  Fritz Reese  <fritzoreese@gmail.com>
+
+       PR fortran/71523
+       * gfortran.dg/pr71523_1.f90: New test.
+       * gfortran.dg/pr71523_2.f90: New test.
+
 2016-07-16  Andreas Schwab  <schwab@linux-m68k.org>
 
        * 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 (file)
index 0000000..7b5b2ab
--- /dev/null
@@ -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 (file)
index 0000000..5be0dd7
--- /dev/null
@@ -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