]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fix ICE with coarrays and submodules [PR80235]
authorAndre Vehreschild <vehre@gcc.gnu.org>
Tue, 24 Sep 2024 12:30:52 +0000 (14:30 +0200)
committerAndre Vehreschild <vehre@gcc.gnu.org>
Thu, 17 Oct 2024 06:56:59 +0000 (08:56 +0200)
Exposing a variable in a module and referencing it in a submodule made
the compiler ICE, because the external variable was not sorted into the
correct module.  In fact the module name was not set where the variable
got built.

gcc/fortran/ChangeLog:

PR fortran/80235

* trans-decl.cc (gfc_build_qualified_array): Make sure the array
is associated to the correct module and being marked as extern.

gcc/testsuite/ChangeLog:

* gfortran.dg/coarray/add_sources/submodule_1_sub.f90: New test.
* gfortran.dg/coarray/submodule_1.f90: New test.

gcc/fortran/trans-decl.cc
gcc/testsuite/gfortran.dg/coarray/add_sources/submodule_1_sub.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/coarray/submodule_1.f90 [new file with mode: 0644]

index 56b6202510e8788d7aa700408fae428df1681c0d..9cced7c02e40f401c1375d35c89e66ec2dbb2a02 100644 (file)
@@ -1066,7 +1066,8 @@ gfc_build_qualified_array (tree decl, gfc_symbol * sym)
                        IDENTIFIER_POINTER (gfc_sym_mangled_identifier (sym))));
          token = build_decl (DECL_SOURCE_LOCATION (decl), VAR_DECL, token_name,
                              token_type);
-         if (sym->attr.use_assoc)
+         if (sym->attr.use_assoc
+             || (sym->attr.host_assoc && sym->attr.used_in_submodule))
            DECL_EXTERNAL (token) = 1;
          else
            TREE_STATIC (token) = 1;
@@ -1091,9 +1092,11 @@ gfc_build_qualified_array (tree decl, gfc_symbol * sym)
 
       if (sym->module && !sym->attr.use_assoc)
        {
+         module_htab_entry *mod
+           = cur_module ? cur_module : gfc_find_module (sym->module);
          pushdecl (token);
          DECL_CONTEXT (token) = sym->ns->proc_name->backend_decl;
-         gfc_module_add_decl (cur_module, token);
+         gfc_module_add_decl (mod, token);
        }
       else if (sym->attr.host_assoc
               && TREE_CODE (DECL_CONTEXT (current_function_decl))
diff --git a/gcc/testsuite/gfortran.dg/coarray/add_sources/submodule_1_sub.f90 b/gcc/testsuite/gfortran.dg/coarray/add_sources/submodule_1_sub.f90
new file mode 100644 (file)
index 0000000..fd177fc
--- /dev/null
@@ -0,0 +1,22 @@
+! This test belongs to submodule_1.f90
+! It is references as additional source in that test.
+! The two code fragments need to be in separate files to show
+! the error of pr80235.
+
+submodule (pr80235) pr80235_sub
+
+contains
+  module subroutine test()
+    implicit none
+    if (var%v /= 42) stop 1
+  end subroutine
+end submodule pr80235_sub
+
+program pr80235_prg
+  use pr80235
+  
+  implicit none
+
+  var%v = 42
+  call test()
+end program
diff --git a/gcc/testsuite/gfortran.dg/coarray/submodule_1.f90 b/gcc/testsuite/gfortran.dg/coarray/submodule_1.f90
new file mode 100644 (file)
index 0000000..d0faef9
--- /dev/null
@@ -0,0 +1,29 @@
+!{ dg-do run }
+!{ dg-additional-sources add_sources/submodule_1_sub.f90 }
+
+! Separating the module and the submodule is needed to show the error.
+! Having all code pieces in one file does not show the error.
+
+module pr80235
+  implicit none
+
+  private
+  public :: test, var
+
+  type T
+    integer :: v
+  end type T
+
+interface
+
+  module subroutine test()
+  end subroutine
+
+end interface
+
+  type(T) :: var[*]
+
+end module pr80235
+
+
+