Hi all,I had originally created this patch in 2018 and we did not get back to it. This results in more restrictive runtime behavior. I will go through the front-end code with another patch to catch this at compile time.
Changelog and new test case. See attached patch. OK for trunk Author: Jerry DeLisle <jvdeli...@gcc.gnu.org> Date: Fri Nov 22 19:29:42 2024 -0800 Fortran: Reject missing comma in format. Standards require rejecting formats where descriptors are not separated by commas. This change allows this the missing comma to be accepted only with -std=legacy. PR fortran/88052 libgfortran/ChangeLog: * io/format.c (parse_format_list): Reject missing comma in format strings by default or if -std=f95 or higher. This is a runtime error. gcc/testsuite/ChangeLog: * gfortran.dg/comma_format_extension_4.f: Add missing comma. * gfortran.dg/dollar_edit_descriptor_2.f: Likewise. * gfortran.dg/fmt_error_9.f: Likewise. * gfortran.dg/fmt_g0_5.f08: Likewise. * gfortran.dg/fmt_t_2.f90: Likewise. * gfortran.dg/pr88052.f90: New test.
diff --git a/gcc/testsuite/gfortran.dg/comma_format_extension_4.f b/gcc/testsuite/gfortran.dg/comma_format_extension_4.f index 30f07e803c5..1d018380f9c 100644 --- a/gcc/testsuite/gfortran.dg/comma_format_extension_4.f +++ b/gcc/testsuite/gfortran.dg/comma_format_extension_4.f @@ -1,7 +1,7 @@ ! PR fortran/13257 -! Note the missing , before i1 in the format. +! Note the missing , after i4 in the format. ! { dg-do run } -! { dg-options "" } +! { dg-options "-std=legacy" } character*6 c write (c,1001) 1 if (c .ne. ' 1 ') STOP 1 diff --git a/gcc/testsuite/gfortran.dg/dollar_edit_descriptor_2.f b/gcc/testsuite/gfortran.dg/dollar_edit_descriptor_2.f index 437f4dfd811..de583f374dc 100644 --- a/gcc/testsuite/gfortran.dg/dollar_edit_descriptor_2.f +++ b/gcc/testsuite/gfortran.dg/dollar_edit_descriptor_2.f @@ -1,5 +1,5 @@ ! { dg-do run } -! { dg-options "-w" } +! { dg-options "-w -std=legacy" } ! PR25545 internal file and dollar edit descriptor. program main character*20 line diff --git a/gcc/testsuite/gfortran.dg/fmt_error_9.f b/gcc/testsuite/gfortran.dg/fmt_error_9.f index 40c73599ac8..2755074054c 100644 --- a/gcc/testsuite/gfortran.dg/fmt_error_9.f +++ b/gcc/testsuite/gfortran.dg/fmt_error_9.f @@ -4,7 +4,7 @@ ! Test case prepared by Jerry DeLisle <jvdeli...@gcc.gnu.org> character(len=25) :: str character(len=132) :: msg, line - str = '(1pd24.15e6)' + str = '(1pd24.15,e6)' line = "initial string" x = 555.25 @@ -19,11 +19,11 @@ if (istat.ne.5006 .or. msg(1:10).ne."Zero width") STOP 4 if (x.ne.555.25) STOP 5 - write (line,'(1pd24.15e11.3)') 1.0d0, 1.234 + write (line,'(1pd24.15,e11.3)') 1.0d0, 1.234 if (line.ne." 1.000000000000000D+00 1.234E+00") STOP 6 str = '(1p2d24.15)' msg = " 1.000000000000000D+00 1.233999967575073D+00That's it!" - write (line,'(1p2d24.15a)') 1.0d0, 1.234, "That's it!" + write (line,'(1p2d24.15,a)') 1.0d0, 1.234, "That's it!" if (line.ne.msg) print *, msg end diff --git a/gcc/testsuite/gfortran.dg/fmt_g0_5.f08 b/gcc/testsuite/gfortran.dg/fmt_g0_5.f08 index d2a97b1ac80..cafd90b94b5 100644 --- a/gcc/testsuite/gfortran.dg/fmt_g0_5.f08 +++ b/gcc/testsuite/gfortran.dg/fmt_g0_5.f08 @@ -6,13 +6,13 @@ program test_g0_special call check_all("(g10.3)", "(f10.3)") call check_all("(g10.3e3)", "(f10.3)") - call check_all("(spg10.3)", "(spf10.3)") - call check_all("(spg10.3e3)", "(spf10.3)") + call check_all("(sp,g10.3)", "(sp,f10.3)") + call check_all("(sp,g10.3e3)", "(sp,f10.3)") !print *, "-----------------------------------" call check_all("(g0)", "(f0.0)") call check_all("(g0.15)", "(f0.0)") - call check_all("(spg0)", "(spf0.0)") - call check_all("(spg0.15)", "(spf0.0)") + call check_all("(sp,g0)", "(sp,f0.0)") + call check_all("(sp,g0.15)", "(sp,f0.0)") contains subroutine check_all(fmt1, fmt2) character(len=*), intent(in) :: fmt1, fmt2 diff --git a/gcc/testsuite/gfortran.dg/fmt_t_2.f90 b/gcc/testsuite/gfortran.dg/fmt_t_2.f90 index 01647655de6..56414c54bfb 100644 --- a/gcc/testsuite/gfortran.dg/fmt_t_2.f90 +++ b/gcc/testsuite/gfortran.dg/fmt_t_2.f90 @@ -12,7 +12,7 @@ read (11, '(a040,t1,040a)', end = 999) foost1 , foost2 if (foost1.ne.foost2) STOP 1 - read (11, '(a032,t2,a032t3,a032)', end = 999) foost1 , foost2, foost3 + read (11, '(a032,t2,a032,t3,a032)', end = 999) foost1 , foost2, foost3 if (foost1(1:32).ne."123456789 123456789 123456789 ") STOP 2 if (foost2(1:32).ne."23456789 123456789 123456789 ") STOP 3 if (foost3(1:32).ne."3456789 123456789 123456789 ") STOP 4 diff --git a/gcc/testsuite/gfortran.dg/pr88052.f90 b/gcc/testsuite/gfortran.dg/pr88052.f90 new file mode 100644 index 00000000000..fa766490ef7 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr88052.f90 @@ -0,0 +1,10 @@ +! { dg-do run } +! F2008 constraint C1002 requires comma between A and F in a format +program badfmt + implicit none + integer :: myerror = 0 + character(40):: fmt = "(AF9.6)" + open (10, status='scratch') + write (10,fmt, iostat=myerror) 'pi =',4*atan(1.0) + if (myerror /= 5006) stop 1 +end program badfmt diff --git a/libgfortran/io/format.c b/libgfortran/io/format.c index f39d6ecc65b..82f7e97878c 100644 --- a/libgfortran/io/format.c +++ b/libgfortran/io/format.c @@ -45,7 +45,8 @@ static const char posint_required[] = "Positive integer required in format", bad_string[] = "Unterminated character constant in format", bad_hollerith[] = "Hollerith constant extends past the end of the format", reversion_error[] = "Exhausted data descriptors in format", - zero_width[] = "Zero width in format descriptor"; + zero_width[] = "Zero width in format descriptor", + comma_missing[] = "Missing comma between descriptors"; /* The following routines support caching format data from parsed format strings into a hash table. This avoids repeatedly parsing duplicate format strings @@ -1233,8 +1234,10 @@ parse_format_list (st_parameter_dt *dtp, bool *seen_dd) goto finished; default: - /* Assume a missing comma, this is a GNU extension */ - goto format_item_1; + /* Assume a missing comma with -std=legacy, GNU extension. */ + if (compile_options.warn_std == 0) + goto format_item_1; + format_error (dtp, tail, comma_missing); } /* Optional comma is a weird between state where we've just finished