Hi all,

Attached patch adds to checks.  In the case of IMPLICIT typing it checks to see if the objects listed in the NAMELIST have defined types andf if not, sets them to the default implicit types.

In the case of IMPLICIT NONE, the types are required be declared before the NAMELIST.   If an object type is found to not be declared already, an error is issued.

One new test case added and one modified to pass.

Regression tested.

OK for trunk?

Regards,

Jerry

fortran: Object types should be declared before use in NAMELIST.

gcc/fortran/ChangeLog:

    PR fortran/98686
    * match.c (gfc_match_namelist): Add checks for IMPLICIT NONE and
    whether the type for each namelist object has been defined before
    the namelist declaration.  For IMPLICIT, set the types so that
    any subsequent use of objects will have their types confirmed.

gcc/testsuite/ChangeLog:

    PR fortran/98686
    * gfortran.dg/namelist_4.f90: Modify.
    * gfortran.dg/namelist_98.f90: New test.

diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
index 2df6191d7e6..3a06f308812 100644
--- a/gcc/fortran/match.c
+++ b/gcc/fortran/match.c
@@ -5536,6 +5536,27 @@ gfc_match_namelist (void)
 	  if (m == MATCH_ERROR)
 	    goto error;
 
+	  if (!gfc_current_ns->seen_implicit_none)
+	    {
+	      /* If the type is not set already, we set it here to the
+		 implicit default type.  It is not allowed to set it
+		 later to any other type.  */
+	      if (sym->ts.type == BT_UNKNOWN)
+		gfc_set_default_type (sym, 0, gfc_current_ns);
+	    }
+	  else
+	    {
+	      /* It is required that members of a namelist be declared
+		 before the namelist.  We check this by checking if the
+		 symbol has a defined type for IMPLICIT NONE.  */
+	      if (sym->ts.type == BT_UNKNOWN)
+		{
+		  gfc_error ("Symbol %qs in namelist %qs at %C must be "
+			     "declared before the namelist is declared.",
+			     sym->name, group_name->name);
+		  gfc_error_check ();
+		}
+	    }
 	  if (sym->attr.in_namelist == 0
 	      && !gfc_add_in_namelist (&sym->attr, sym->name, NULL))
 	    goto error;
diff --git a/gcc/testsuite/gfortran.dg/namelist_4.f90 b/gcc/testsuite/gfortran.dg/namelist_4.f90
index 538bceaa4b6..4e021253f01 100644
--- a/gcc/testsuite/gfortran.dg/namelist_4.f90
+++ b/gcc/testsuite/gfortran.dg/namelist_4.f90
@@ -27,14 +27,14 @@ END module M1
 program P1
 CONTAINS
 ! This has the additional wrinkle of a reference to the object.
+  INTEGER FUNCTION F2()
+    F2=1
+  END FUNCTION
   INTEGER FUNCTION F1()
     NAMELIST /NML3/ F2 ! { dg-error "PROCEDURE attribute conflicts" }
 ! Used to ICE here
-    f2 = 1             ! { dg-error "is not a VALUE" }
+    f2 = 1             ! { dg-error "is not a variable" }
     F1=1
   END FUNCTION
-  INTEGER FUNCTION F2()
-    F2=1
-  END FUNCTION
 END
 
diff --git a/gcc/testsuite/gfortran.dg/namelist_98.f90 b/gcc/testsuite/gfortran.dg/namelist_98.f90
new file mode 100644
index 00000000000..19a7e869f92
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/namelist_98.f90
@@ -0,0 +1,11 @@
+! { dg-do compile }
+! pr98686
+  implicit none
+  real    :: x, m
+  namelist /NML/ x, m, q ! { dg-error "must be declared before the namelist*" }
+  integer :: q
+  x = 1.0
+  m = 2.0
+  q = 3
+  write(*, nml=NML)
+end

Reply via email to