https://gcc.gnu.org/g:17582084fad3a0fbf72a83524a4100d2eb802107

commit r16-6748-g17582084fad3a0fbf72a83524a4100d2eb802107
Author: Jerry DeLisle <[email protected]>
Date:   Mon Jan 12 18:45:05 2026 -0800

    Fortran: Detect missing quote in namelist read.
    
            PR libfortran/123012
    
    libgfortran/ChangeLog:
    
            * io/list_read.c (read_character): Add new check after
            get_string and provide better comments.
    
    gcc/testsuite/ChangeLog:
    
            * gfortran.dg/namelist_101.f90: New test.

Diff:
---
 gcc/testsuite/gfortran.dg/namelist_101.f90 | 16 ++++++++++++++++
 libgfortran/io/list_read.c                 | 14 ++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/gcc/testsuite/gfortran.dg/namelist_101.f90 
b/gcc/testsuite/gfortran.dg/namelist_101.f90
new file mode 100644
index 000000000000..409c568f53f3
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/namelist_101.f90
@@ -0,0 +1,16 @@
+! { dg-do run )
+! { dg-shouldfail "Missing quote" }
+program nml_quotes_bug
+  implicit none
+  integer      :: unit = 10
+  character(8) :: c1, c2
+  namelist /tovs_obs_chan/ c1, c2
+  open (unit ,file="nml-quotes-bug.nml")
+  write(unit,*) "&tovs_obs_chan"
+  write(unit,*) "  c1 = '1',"
+  write(unit,*) "  c2 =  2a ,"
+  write(unit,*) "/"
+  rewind(unit)
+  read (unit ,nml=tovs_obs_chan)
+  close(unit ,status="delete")
+end program nml_quotes_bug
diff --git a/libgfortran/io/list_read.c b/libgfortran/io/list_read.c
index 2aadc8f4d3c1..0d16640a9000 100644
--- a/libgfortran/io/list_read.c
+++ b/libgfortran/io/list_read.c
@@ -1314,6 +1314,10 @@ read_character (st_parameter_dt *dtp, int length 
__attribute__ ((unused)))
 
        CASE_SEPARATORS:
        case EOF:
+         /* At this point we have been reading a string of digits. Now we see
+            the end of these digits without seeing the closing quote and not
+            seeing the '*' for a repeat count.  When in namelist mode, if it
+            was a string of digits it should have had the closing quote.  */
          if (dtp->u.p.namelist_mode)
            {
              snprintf (message, IOMSG_LEN, "Missing quote while reading item 
%d",
@@ -1367,6 +1371,16 @@ read_character (st_parameter_dt *dtp, int length 
__attribute__ ((unused)))
 
  get_string:
 
+  /* We could be at the beginning of a string or partially through a string
+     that began with all digits. Either way, the quote character for a namelist
+     read should have been set.  */
+  if (dtp->u.p.namelist_mode && (quote == ' '))
+    {
+      snprintf (message, IOMSG_LEN, "Missing quote while reading item %d",
+               dtp->u.p.item_count);
+      generate_error (&dtp->common, LIBERROR_READ_VALUE, message);
+    }
+
   for (;;)
     {
       if ((c = next_char (dtp)) == EOF)

Reply via email to