Nested functions are permitted for C but not C++ as extension.
They are also permitted for Fortran, which generates DECL_CONTEXT
== NAMESPACE_DECL for module variables.

That causes the gcc_assert (decl_function_context (decl) == info->context)
to fail in tree-nested.c's lookup_field_for_decl.

The call happens in convert_local_reference_stmt for:
2524        case GIMPLE_ASSIGN:
2525          if (gimple_clobber_p (stmt))
2528              if (DECL_P (lhs)
2529                  && !use_pointer_in_frame (lhs)
2530                  && lookup_field_for_decl (info, lhs, NO_INSERT))

The latter runs into the assert mentioned above. And the
'= {CLOBBER}' occurs in gfortran due to the intent(out).

As additional ingredient, a nested (internal) procedure involved,
obviously as otherwise tree-nested.c wouldn't be involved.

The patch fixes the assert and in terms of the assert it makes
sense, but I am not sure whether there are assumptions
elsewhere which are wrong for NAMESPACE_DECL.

OK for mainline? GCC 10?

Tobias

-----------------
Mentor Graphics (Deutschland) GmbH, Arnulfstrasse 201, 80634 München 
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Frank 
Thürauf
tree-nested: Update assert for Fortran module vars [PR97927]

gcc/ChangeLog:

	PR fortran/97927
	* tree-nested.c (lookup_field_for_decl): Also permit
	that the var is a Fortran module var (= namespace context).

gcc/testsuite/ChangeLog:

	PR fortran/97927
	* gfortran.dg/module_variable_3.f90: New test.

 gcc/testsuite/gfortran.dg/module_variable_3.f90 | 37 +++++++++++++++++++++++++
 gcc/tree-nested.c                               |  3 +-
 2 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/gfortran.dg/module_variable_3.f90 b/gcc/testsuite/gfortran.dg/module_variable_3.f90
new file mode 100644
index 00000000000..0dae6d5bdd5
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/module_variable_3.f90
@@ -0,0 +1,37 @@
+! { dg-do compile }
+! { dg-additional-options "-fdump-tree-original" }
+!
+! PR fortran/97927
+!
+! Did ICE due to the in tree-nested.c due to {clobber}
+!
+
+module mpi2
+ interface
+   subroutine MPI_Allreduce(i)
+     implicit none
+     INTEGER, OPTIONAL, INTENT(OUT) :: i
+   end subroutine MPI_Allreduce
+ end interface
+end module
+
+module modmpi
+  implicit none
+  integer ierror  ! module variable = context NAMESPACE_DECL
+end module
+
+subroutine exxengy
+  use modmpi
+  use mpi2, only: mpi_allreduce
+  implicit none
+
+  ! intent(out) implies: ierror = {clobber}
+  call mpi_allreduce(ierror)
+
+contains
+  subroutine zrho2
+    return
+  end subroutine
+end subroutine
+
+! { dg-final { scan-tree-dump "ierror = {CLOBBER};" "original" } }
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
index addd6eef9ab..cedeccac40b 100644
--- a/gcc/tree-nested.c
+++ b/gcc/tree-nested.c
@@ -382,7 +382,8 @@ static tree
 lookup_field_for_decl (struct nesting_info *info, tree decl,
 		       enum insert_option insert)
 {
-  gcc_checking_assert (decl_function_context (decl) == info->context);
+  gcc_checking_assert (decl_function_context (decl) == info->context
+		       || TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL);
 
   if (insert == NO_INSERT)
     {

Reply via email to