https://gcc.gnu.org/g:a1b441efc42938b7b2b14e9f23b1ec351d2da098

commit a1b441efc42938b7b2b14e9f23b1ec351d2da098
Author: Paul Thomas <pa...@gcc.gnu.org>
Date:   Sun Jul 21 17:48:47 2024 +0100

    Fortran: Fix regression caused by r14-10477 [PR59104]
    
    2024-07-21  Paul Thomas  <pa...@gcc.gnu.org>
    
    gcc/fortran
            PR fortran/59104
            * gfortran.h : Add decl_order to gfc_symbol.
            * symbol.cc : Add static next_decl_order..
            (gfc_set_sym_referenced): Set symbol decl_order.
            * trans-decl.cc : Include dependency.h.
            (decl_order): Replace symbol declared_at.lb->location with
            decl_order.
    
    gcc/testsuite/
            PR fortran/59104
            * gfortran.dg/dependent_decls_3.f90: New test.

Diff:
---
 gcc/fortran/gfortran.h                          |  3 +++
 gcc/fortran/symbol.cc                           |  6 ++++++
 gcc/fortran/trans-decl.cc                       |  2 +-
 gcc/testsuite/gfortran.dg/dependent_decls_3.f90 | 26 +++++++++++++++++++++++++
 4 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 3e20821cceae..f922bf3bb991 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -1893,6 +1893,9 @@ typedef struct gfc_symbol
      points to C and B's is NULL.  */
   struct gfc_common_head* common_head;
 
+  /* Make sure initialization code is generated in the correct order.  */
+  int decl_order;
+
   gfc_namelist *namelist, *namelist_tail;
 
   /* The tlink field is used in the front end to carry the module
diff --git a/gcc/fortran/symbol.cc b/gcc/fortran/symbol.cc
index 2f326492d5fb..a8479b862e39 100644
--- a/gcc/fortran/symbol.cc
+++ b/gcc/fortran/symbol.cc
@@ -96,6 +96,9 @@ 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_decl_order = 1;
 
 gfc_namespace *gfc_current_ns;
 gfc_namespace *gfc_global_ns_list;
@@ -940,6 +943,9 @@ gfc_set_sym_referenced (gfc_symbol *sym)
     return;
 
   sym->attr.referenced = 1;
+
+  /* Remember the declaration order.  */
+  sym->decl_order = next_decl_order++;
 }
 
 
diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc
index 436a4051c057..7593decc6f04 100644
--- a/gcc/fortran/trans-decl.cc
+++ b/gcc/fortran/trans-decl.cc
@@ -842,7 +842,7 @@ gfc_allocate_lang_decl (tree decl)
 static bool
 decl_order (gfc_symbol *sym1, gfc_symbol *sym2)
 {
-  if (sym1->declared_at.lb->location > sym2->declared_at.lb->location)
+  if (sym1->decl_order > sym2->decl_order)
     return true;
   else
     return false;
diff --git a/gcc/testsuite/gfortran.dg/dependent_decls_3.f90 
b/gcc/testsuite/gfortran.dg/dependent_decls_3.f90
new file mode 100644
index 000000000000..93862b8ccdca
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dependent_decls_3.f90
@@ -0,0 +1,26 @@
+! { dg-do run }
+!
+! Fix a regression caused by the fix for PR59104.
+!
+! Contributed by Harald Anlauf  <anl...@gcc.gnu.org>
+!
+program p
+  implicit none
+  integer, parameter :: nx = 64, ny = 32
+  real               :: x(nx,ny), s(nx/2,ny), d(nx/2,ny)
+
+  s = 0.0
+  d = 0.0
+  call sub (x,s,d)
+  if (sum(s) .ne. 256) stop 1
+  if (sum(d) .ne. 256) stop 2  ! Stopped with sum(d) == 0.
+contains
+  subroutine sub  (v, w, d)
+    real, intent(in)  :: v(:,:)
+    real, intent(out), dimension (size (v,dim=1)/4,size (v,dim=2)/2) :: w, d
+    w = 1.0
+    d = 1.0
+    if (any (shape (w) .ne. [nx/4, ny/2])) stop 3
+    if (any (shape (d) .ne. [nx/4, ny/2])) print *, shape (d)  ! Printed "0 0" 
here
+  end subroutine sub
+end

Reply via email to