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