This patch was simple and obvious. I decided to add additional comments to make
things clearer. This addresses Harald's discovery (new test case).
I will commit tomorrow if no objections.
Regression tested on x86_64. New test case provided.
Regards,
Jerry
commit 5882cd9b730c8ec8624d7eedcd72edac2dbabeac
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 --git a/gcc/testsuite/gfortran.dg/namelist_101.f90
b/gcc/testsuite/gfortran.dg/namelist_101.f90
new file mode 100644
index 00000000000..409c568f53f
--- /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 2aadc8f4d3c..0d16640a900 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)