https://gcc.gnu.org/g:94e4661fee27c5b1362e02690c5047e0b543fc9a

commit r14-10480-g94e4661fee27c5b1362e02690c5047e0b543fc9a
Author: Paul Thomas <pa...@gcc.gnu.org>
Date:   Sat Jul 20 10:42:40 2024 +0100

    Revert "Fortran: Auto array allocation with function dependencies [PR59104]"
    
    This reverts commit 5034af8223c0db07cdec01cef70048ec44cdd47b.

Diff:
---
 gcc/fortran/dependency.cc                       | 82 -----------------------
 gcc/fortran/dependency.h                        |  4 +-
 gcc/fortran/error.cc                            |  2 +-
 gcc/fortran/gfortran.h                          |  6 +-
 gcc/fortran/symbol.cc                           | 10 +++
 gcc/fortran/trans-array.cc                      | 15 +----
 gcc/fortran/trans-decl.cc                       | 51 ++------------
 gcc/fortran/trans.cc                            |  5 +-
 gcc/fortran/trans.h                             |  3 +-
 gcc/testsuite/gfortran.dg/dependent_decls_2.f90 | 89 -------------------------
 10 files changed, 29 insertions(+), 238 deletions(-)

diff --git a/gcc/fortran/dependency.cc b/gcc/fortran/dependency.cc
index 15edf1af9dff..bafe8cbc5bc3 100644
--- a/gcc/fortran/dependency.cc
+++ b/gcc/fortran/dependency.cc
@@ -2497,85 +2497,3 @@ gfc_omp_expr_prefix_same (gfc_expr *lexpr, gfc_expr 
*rexpr)
 
   return true;
 }
-
-
-/* gfc_function_dependency returns true for non-dummy symbols with dependencies
-   on an old-fashioned function result (ie. proc_name = proc_name->result).
-   This is used to ensure that initialization code appears after the function
-   result is treated and that any mutual dependencies between these symbols are
-   respected.  */
-
-static bool
-dependency_fcn (gfc_expr *e, gfc_symbol *sym,
-                int *f ATTRIBUTE_UNUSED)
-{
-  if (e == NULL)
-    return false;
-
-  if (e && e->expr_type == EXPR_VARIABLE)
-    {
-      if (e->symtree && e->symtree->n.sym == sym)
-       return true;
-      /* Recurse to see if this symbol is dependent on the function result. If
-        so an indirect dependence exists, which should be handled in the same
-        way as a direct dependence. The recursion is prevented from being
-        infinite by statement order.  */
-      else if (e->symtree && e->symtree->n.sym)
-       return gfc_function_dependency (e->symtree->n.sym, sym);
-    }
-
-  return false;
-}
-
-
-bool
-gfc_function_dependency (gfc_symbol *sym, gfc_symbol *proc_name)
-{
-  bool dep = false;
-
-  if (proc_name && proc_name->attr.function
-      && proc_name == proc_name->result
-      && !(sym->attr.dummy || sym->attr.result))
-    {
-      if (sym->fn_result_dep)
-       return true;
-
-      if (sym->as && sym->as->type == AS_EXPLICIT)
-       {
-         for (int dim = 0; dim < sym->as->rank; dim++)
-           {
-             if (sym->as->lower[dim]
-                 && sym->as->lower[dim]->expr_type != EXPR_CONSTANT)
-               dep = gfc_traverse_expr (sym->as->lower[dim], proc_name,
-                                        dependency_fcn, 0);
-             if (dep)
-               {
-                 sym->fn_result_dep = 1;
-                 return true;
-               }
-             if (sym->as->upper[dim]
-                 && sym->as->upper[dim]->expr_type != EXPR_CONSTANT)
-               dep = gfc_traverse_expr (sym->as->upper[dim], proc_name,
-                                        dependency_fcn, 0);
-             if (dep)
-               {
-                 sym->fn_result_dep = 1;
-                 return true;
-               }
-           }
-       }
-
-      if (sym->ts.type == BT_CHARACTER
-         && sym->ts.u.cl && sym->ts.u.cl->length
-         && sym->ts.u.cl->length->expr_type != EXPR_CONSTANT)
-       dep = gfc_traverse_expr (sym->ts.u.cl->length, proc_name,
-                                dependency_fcn, 0);
-      if (dep)
-       {
-         sym->fn_result_dep = 1;
-         return true;
-       }
-    }
-
-  return false;
- }
diff --git a/gcc/fortran/dependency.h b/gcc/fortran/dependency.h
index 8f172f86f08f..ea4bd04b0e82 100644
--- a/gcc/fortran/dependency.h
+++ b/gcc/fortran/dependency.h
@@ -23,7 +23,7 @@ enum gfc_dep_check
 {
   NOT_ELEMENTAL,        /* Not elemental case: normal dependency check.  */
   ELEM_CHECK_VARIABLE,  /* Test whether variables overlap.  */
-  ELEM_DONT_CHECK_VARIABLE  /* Test whether variables overlap only if used
+  ELEM_DONT_CHECK_VARIABLE  /* Test whether variables overlap only if used 
                               in an expression.  */
 };
 
@@ -43,5 +43,3 @@ bool gfc_are_equivalenced_arrays (gfc_expr *, gfc_expr *);
 bool gfc_omp_expr_prefix_same (gfc_expr *, gfc_expr *);
 
 gfc_expr * gfc_discard_nops (gfc_expr *);
-
-bool gfc_function_dependency (gfc_symbol *, gfc_symbol *);
diff --git a/gcc/fortran/error.cc b/gcc/fortran/error.cc
index 60f607ecc4f2..65e38b0e8667 100644
--- a/gcc/fortran/error.cc
+++ b/gcc/fortran/error.cc
@@ -892,7 +892,7 @@ error_print (const char *type, const char *format0, va_list 
argp)
 #else
              m = INTTYPE_MAXIMUM (ptrdiff_t);
 #endif
-             m = 2 * m + 1;
+             m = 2 * m + 1;  
              error_uinteger (a & m);
            }
          else
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 5b7c27a5597c..de3d9e25911b 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -1887,6 +1887,10 @@ typedef struct gfc_symbol
      points to C and B's is NULL.  */
   struct gfc_common_head* common_head;
 
+  /* Make sure setup code for dummy arguments is generated in the correct
+     order.  */
+  int dummy_order;
+
   gfc_namelist *namelist, *namelist_tail;
 
   /* The tlink field is used in the front end to carry the module
@@ -1925,8 +1929,6 @@ typedef struct gfc_symbol
   unsigned forall_index:1;
   /* Set if the symbol is used in a function result specification .  */
   unsigned fn_result_spec:1;
-  /* Set if the symbol spec. depends on an old-style function result.  */
-  unsigned fn_result_dep:1;
   /* Used to avoid multiple resolutions of a single symbol.  */
   /* = 2 if this has already been resolved as an intrinsic,
        in gfc_resolve_intrinsic,
diff --git a/gcc/fortran/symbol.cc b/gcc/fortran/symbol.cc
index 2f326492d5fb..5db3c887127b 100644
--- a/gcc/fortran/symbol.cc
+++ b/gcc/fortran/symbol.cc
@@ -96,6 +96,11 @@ const mstring dtio_procs[] =
     minit ("_dtio_unformatted_write", DTIO_WUF),
 };
 
+/* This is to make sure the backend generates setup code in the correct
+   order.  */
+
+static int next_dummy_order = 1;
+
 
 gfc_namespace *gfc_current_ns;
 gfc_namespace *gfc_global_ns_list;
@@ -936,10 +941,15 @@ conflict:
 void
 gfc_set_sym_referenced (gfc_symbol *sym)
 {
+
   if (sym->attr.referenced)
     return;
 
   sym->attr.referenced = 1;
+
+  /* Remember which order dummy variables are accessed in.  */
+  if (sym->attr.dummy)
+    sym->dummy_order = next_dummy_order++;
 }
 
 
diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index b621f42917c9..761f0a425078 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -6871,7 +6871,6 @@ gfc_trans_auto_array_allocation (tree decl, gfc_symbol * 
sym,
   tree space;
   tree inittree;
   bool onstack;
-  bool back;
 
   gcc_assert (!(sym->attr.pointer || sym->attr.allocatable));
 
@@ -6883,12 +6882,6 @@ gfc_trans_auto_array_allocation (tree decl, gfc_symbol * 
sym,
   gcc_assert (GFC_ARRAY_TYPE_P (type));
   onstack = TREE_CODE (type) != POINTER_TYPE;
 
-  /* In the case of non-dummy symbols with dependencies on an old-fashioned
-     function result (ie. proc_name = proc_name->result), gfc_add_init_cleanup
-     must be called with the last, optional argument false so that the alloc-
-     ation occurs after the processing of the result.  */
-  back = sym->fn_result_dep;
-
   gfc_init_block (&init);
 
   /* Evaluate character string length.  */
@@ -6916,8 +6909,7 @@ gfc_trans_auto_array_allocation (tree decl, gfc_symbol * 
sym,
 
   if (onstack)
     {
-      gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE,
-                           back);
+      gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
       return;
     }
 
@@ -7004,11 +6996,10 @@ gfc_trans_auto_array_allocation (tree decl, gfc_symbol 
* sym,
       addr = fold_build1_loc (gfc_get_location (&sym->declared_at),
                              ADDR_EXPR, TREE_TYPE (decl), space);
       gfc_add_modify (&init, decl, addr);
-      gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE,
-                           back);
+      gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
       tmp = NULL_TREE;
     }
-  gfc_add_init_cleanup (block, inittree, tmp, back);
+  gfc_add_init_cleanup (block, inittree, tmp);
 }
 
 
diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc
index 219d9eb797fa..1a319b27449b 100644
--- a/gcc/fortran/trans-decl.cc
+++ b/gcc/fortran/trans-decl.cc
@@ -49,7 +49,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "omp-general.h"
 #include "attr-fnspec.h"
 #include "tree-iterator.h"
-#include "dependency.h"
 
 #define MAX_LABEL_VALUE 99999
 
@@ -833,19 +832,6 @@ gfc_allocate_lang_decl (tree decl)
     DECL_LANG_SPECIFIC (decl) = ggc_cleared_alloc<struct lang_decl> ();
 }
 
-
-/* Determine order of two symbol declarations.  */
-
-static bool
-decl_order (gfc_symbol *sym1, gfc_symbol *sym2)
-{
-  if (sym1->declared_at.lb->location > sym2->declared_at.lb->location)
-    return true;
-  else
-    return false;
-}
-
-
 /* Remember a symbol to generate initialization/cleanup code at function
    entry/exit.  */
 
@@ -863,34 +849,18 @@ gfc_defer_symbol_init (gfc_symbol * sym)
   last = head = sym->ns->proc_name;
   p = last->tlink;
 
-  gfc_function_dependency (sym, head);
-
   /* Make sure that setup code for dummy variables which are used in the
      setup of other variables is generated first.  */
   if (sym->attr.dummy)
     {
       /* Find the first dummy arg seen after us, or the first non-dummy arg.
-        This is a circular list, so don't go past the head.  */
+         This is a circular list, so don't go past the head.  */
       while (p != head
-            && (!p->attr.dummy || decl_order (p, sym)))
-       {
-         last = p;
-         p = p->tlink;
-       }
-    }
-  else if (sym->fn_result_dep)
-    {
-      /* In the case of non-dummy symbols with dependencies on an old-fashioned
-     function result (ie. proc_name = proc_name->result), make sure that the
-     order in the tlink chain is such that the code appears in declaration
-     order. This ensures that mutual dependencies between these symbols are
-     respected.  */
-      while (p != head
-            && (!p->attr.result || decl_order (sym, p)))
-       {
-         last = p;
-         p = p->tlink;
-       }
+             && (!p->attr.dummy || p->dummy_order > sym->dummy_order))
+        {
+          last = p;
+          p = p->tlink;
+        }
     }
   /* Insert in between last and p.  */
   last->tlink = sym;
@@ -4206,19 +4176,12 @@ gfc_trans_auto_character_variable (gfc_symbol * sym, 
gfc_wrapped_block * block)
   stmtblock_t init;
   tree decl;
   tree tmp;
-  bool back;
 
   gcc_assert (sym->backend_decl);
   gcc_assert (sym->ts.u.cl && sym->ts.u.cl->length);
 
   gfc_init_block (&init);
 
-  /* In the case of non-dummy symbols with dependencies on an old-fashioned
-     function result (ie. proc_name = proc_name->result), gfc_add_init_cleanup
-     must be called with the last, optional argument false so that the process
-     ing of the character length occurs after the processing of the result.  */
-  back = sym->fn_result_dep;
-
   /* Evaluate the string length expression.  */
   gfc_conv_string_length (sym->ts.u.cl, NULL, &init);
 
@@ -4231,7 +4194,7 @@ gfc_trans_auto_character_variable (gfc_symbol * sym, 
gfc_wrapped_block * block)
   tmp = fold_build1_loc (input_location, DECL_EXPR, TREE_TYPE (decl), decl);
   gfc_add_expr_to_block (&init, tmp);
 
-  gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE, back);
+  gfc_add_init_cleanup (block, gfc_finish_block (&init), NULL_TREE);
 }
 
 /* Set the initial value of ASSIGN statement auxiliary variable explicitly.  */
diff --git a/gcc/fortran/trans.cc b/gcc/fortran/trans.cc
index 721823c251d5..badad6ae8927 100644
--- a/gcc/fortran/trans.cc
+++ b/gcc/fortran/trans.cc
@@ -2803,15 +2803,14 @@ gfc_start_wrapped_block (gfc_wrapped_block* block, tree 
code)
 /* Add a new pair of initializers/clean-up code.  */
 
 void
-gfc_add_init_cleanup (gfc_wrapped_block* block, tree init, tree cleanup,
-                     bool back)
+gfc_add_init_cleanup (gfc_wrapped_block* block, tree init, tree cleanup)
 {
   gcc_assert (block);
 
   /* The new pair of init/cleanup should be "wrapped around" the existing
      block of code, thus the initialization is added to the front and the
      cleanup to the back.  */
-  add_expr_to_chain (&block->init, init, !back);
+  add_expr_to_chain (&block->init, init, true);
   add_expr_to_chain (&block->cleanup, cleanup, false);
 }
 
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index dc8e91c904f3..2e10ce1a9b34 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -471,8 +471,7 @@ void gfc_conv_class_to_class (gfc_se *, gfc_expr *, 
gfc_typespec, bool, bool,
 void gfc_start_wrapped_block (gfc_wrapped_block* block, tree code);
 /* Add a pair of init/cleanup code to the block.  Each one might be a
    NULL_TREE if not required.  */
-void gfc_add_init_cleanup (gfc_wrapped_block* block, tree init, tree cleanup,
-                          bool back = false);
+void gfc_add_init_cleanup (gfc_wrapped_block* block, tree init, tree cleanup);
 /* Finalize the block, that is, create a single expression encapsulating the
    original code together with init and clean-up code.  */
 tree gfc_finish_wrapped_block (gfc_wrapped_block* block);
diff --git a/gcc/testsuite/gfortran.dg/dependent_decls_2.f90 
b/gcc/testsuite/gfortran.dg/dependent_decls_2.f90
deleted file mode 100644
index 73c84ea3bc50..000000000000
--- a/gcc/testsuite/gfortran.dg/dependent_decls_2.f90
+++ /dev/null
@@ -1,89 +0,0 @@
-! { dg-do run }
-!
-! Fix for PR59104 in which the dependence on the old style function result
-! was not taken into account in the ordering of auto array allocation and
-! characters with dependent lengths.
-!
-! Contributed by Tobias Burnus  <bur...@gcc.gnu.org>
-!
-module m
-   implicit none
-   integer, parameter :: dp = kind([double precision::])
-   contains
-      function f(x)
-         integer, intent(in) :: x
-         real(dp) f(x/2)
-         real(dp) g(x/2)
-         integer y(size (f)+1)              ! This was the original problem
-         integer z(size (f) + size (y))     ! Found in development of the fix
-         integer w(size (f) + size (y) + x) ! Check dummy is OK
-         integer :: l1(size(y))
-         integer :: l2(size(z))
-         integer :: l3(size(w))
-         f = 10.0
-         y = 1                              ! Stop -Wall from complaining
-         z = 1; g = 1; w = 1; l1 = 1; l2 = 1; l3 = 1
-         if (size (f) .ne. 1) stop 1
-         if (size (g) .ne. 1) stop 2
-         if (size (y) .ne. 2) stop 3
-         if (size (z) .ne. 3) stop 4
-         if (size (w) .ne. 5) stop 5
-         if (size (l1) .ne. 2) stop 6       ! Check indirect dependencies
-         if (size (l2) .ne. 3) stop 7
-         if (size (l3) .ne. 5) stop 8
-
-      end function f
-      function e(x) result(f)
-         integer, intent(in) :: x
-         real(dp) f(x/2)
-         real(dp) g(x/2)
-         integer y(size (f)+1)
-         integer z(size (f) + size (y))     ! As was this.
-         integer w(size (f) + size (y) + x)
-         integer :: l1(size(y))
-         integer :: l2(size(z))
-         integer :: l3(size(w))
-         f = 10.0
-         y = 1; z = 1; g = 1; w = 1; l1 = 1; l2 = 1; l3 = 1
-         if (size (f) .ne. 2) stop 9
-         if (size (g) .ne. 2) stop 10
-         if (size (y) .ne. 3) stop 11
-         if (size (z) .ne. 5) stop 12
-         if (size (w) .ne. 9) stop 13
-         if (size (l1) .ne. 3) stop 14      ! Check indirect dependencies
-         if (size (l2) .ne. 5) stop 15
-         if (size (l3) .ne. 9) stop 16
-      end function
-      function d(x)  ! After fixes to arrays, what was needed was known!
-        integer, intent(in) :: x
-        character(len = x/2) :: d
-        character(len = len (d)) :: line
-        character(len = len (d) + len (line)) :: line2
-        character(len = len (d) + len (line) + x) :: line3
-! Commented out lines give implicit type warnings with gfortran and nagfor
-!        character(len = len (d)) :: line4 (len (line3))
-        character(len = len (line3)) :: line4 (len (line3))
-!        character(len = size(len4, 1)) :: line5
-        line = repeat ("a", len (d))
-        line2 = repeat ("b", x)
-        line3 = repeat ("c", len (line3))
-        if (len (line2) .ne. x) stop 17
-        if (line3 .ne. "cccccccc") stop 18
-        d = line
-        line4 = line3
-        if (size (line4) .ne. 8) stop 19
-        if (any (line4 .ne. "cccccccc")) stop 20
-      end
-end module m
-
-program p
-   use m
-   implicit none
-   real(dp) y
-
-   y = sum (f (2))
-   if (int (y) .ne. 10) stop 21
-   y = sum (e (4))
-   if (int (y) .ne. 20) stop 22
-   if (d (4) .ne. "aa") stop 23
-end program p

Reply via email to