--- /dev/null
+! { dg-do run }
+!
+! PR fortran/114304
+!
+! Ensure that '\t' (tab) is supported as separator in list-directed input
+! While not really standard conform, this is widely used in user input and
+! widely supported.
+!
+
+use iso_c_binding
+implicit none
+character(len=*,kind=c_char), parameter :: tab = C_HORIZONTAL_TAB
+
+! Accept '<tab>' as variant to ' ' as separator
+! Check that <carriage_return><new line> and <new_line> are handled
+
+character(len=*,kind=c_char), parameter :: nml_str &
+ = '&inparm'//C_CARRIAGE_RETURN // C_NEW_LINE // &
+ 'first'//tab//'='//tab//' .true.'// C_NEW_LINE // &
+ ' , other'//tab//' ='//tab//'3'//tab//', 2'//tab//'/'
+
+! Check that <carriage_return> is handled,
+
+! Note: For new line, Unix uses \n, Windows \r\n but old Apple systems used '\r'
+!
+! Gfortran does not seem to support all \r, but the following is supported
+! since ages, ! which seems to be a gfortran extension as ifort and flang don't like it.
+
+character(len=*,kind=c_char), parameter :: nml_str2 &
+ = '&inparm'//C_CARRIAGE_RETURN // C_NEW_LINE // &
+ 'first'//C_NEW_LINE//'='//tab//' .true.'// C_CARRIAGE_RETURN // &
+ ' , other'//tab//' ='//tab//'3'//tab//', 2'//tab//'/'
+
+character(len=*,kind=c_char), parameter :: str &
+ = tab//'1'//tab//'2,'//tab//'3'//tab//',4'//tab//','//tab//'5'//tab//'/'
+character(len=*,kind=c_char), parameter :: str2 &
+ = tab//'1'//tab//'2;'//tab//'3'//tab//';4'//tab//';'//tab//'5'//tab//'/'
+logical :: first
+integer :: other(4)
+integer :: ints(6)
+namelist /inparm/ first , other
+
+other = 1
+
+open(99, file="test.inp")
+write(99, '(a)') nml_str
+rewind(99)
+read(99,nml=inparm)
+close(99, status="delete")
+
+if (.not.first .or. any (other /= [3,2,1,1])) stop 1
+
+other = 9
+
+open(99, file="test.inp")
+write(99, '(a)') nml_str2
+rewind(99)
+read(99,nml=inparm)
+close(99, status="delete")
+
+if (.not.first .or. any (other /= [3,2,9,9])) stop 2
+
+ints = 66
+
+open(99, file="test.inp", decimal='point')
+write(99, '(a)') str
+rewind(99)
+read(99,*) ints
+close(99, status="delete")
+
+if (any (ints /= [1,2,3,4,5,66])) stop 3
+
+ints = 77
+
+open(99, file="test.inp", decimal='comma')
+write(99, '(a)') str2
+rewind(99)
+read(99,*) ints
+close(99, status="delete")
+
+if (any (ints /= [1,2,3,4,5,77])) stop 4
+end
--- /dev/null
+! { dg-do run }
+!
+! PR fortran/114304
+!
+! See also PR fortran/105473
+!
+! Testing: Does list-directed reading an integer/real allow some non-integer input?
+!
+! Note: GCC result comments before fix of this PR.
+
+ implicit none
+ call t(.true., 'comma', ';') ! No error shown
+ call t(.false., 'point', ';') ! /!\ gfortran: no error, others: error
+ call t(.false., 'comma', ',') ! Error shown
+ call t(.true., 'point', ',') ! No error shown
+ call t(.false., 'comma', '.') ! Error shown
+ call t(.false., 'point', '.') ! Error shown
+ call t(.false., 'comma', '5.') ! Error shown
+ call t(.false., 'point', '5.') ! gfortran/flang: Error shown, ifort: no error
+ call t(.false., 'comma', '5,') ! gfortran: error; others: no error
+ call t(.true., 'point', '5,') ! No error shown
+ call t(.true., 'comma', '5;') ! No error shown
+ call t(.false., 'point', '5;') ! /!\ gfortran: no error shown, others: error
+ call t(.true., 'comma', '7 .') ! No error shown
+ call t(.true., 'point', '7 .') ! No error shown
+ call t(.true., 'comma', '7 ,') ! /!\ gfortran: error; others: no error
+ call t(.true., 'point', '7 ,') ! No error shown
+ call t(.true., 'comma', '7 ;') ! No error shown
+ call t(.true., 'point', '7 ;') ! No error shown
+
+! print *, '---------------'
+
+ call t(.false., 'comma', '8.', .true.) ! Error shown
+ call t(.true., 'point', '8.', .true.) ! gfortran/flang: Error shown, ifort: no error
+ call t(.true., 'comma', '8,', .true.) ! gfortran: error; others: no error
+ call t(.true., 'point', '8,', .true.) ! No error shown
+ call t(.true., 'comma', '8;', .true.) ! No error shown
+ call t(.false., 'point', '8;', .true.) ! /!\ gfortran: no error shown, others: error
+ call t(.true., 'comma', '9 .', .true.) ! No error shown
+ call t(.true., 'point', '9 .', .true.) ! No error shown
+ call t(.true., 'comma', '9 ,', .true.) ! /!\ gfortran: error; others: no error
+ call t(.true., 'point', '9 ,', .true.) ! No error shown
+ call t(.true., 'comma', '9 ;', .true.) ! No error shown
+ call t(.true., 'point', '9 ;', .true.) ! No error shown
+ call t(.false., 'comma', '3,3.', .true.) ! Error shown
+ call t(.false., 'point', '3.3.', .true.) ! Error shown
+ call t(.false., 'comma', '3,3,', .true.) ! gfortran/flang: no error; ifort: error
+ call t(.true., 'comma', '3,3;', .true.) ! No error shown
+ call t(.false., 'point', '3.3;', .true.) ! gfortran/flang: no error; ifort: error
+ call t(.true., 'comma', '4,4 .', .true.) ! N error shown
+ call t(.true., 'point', '4.4 .', .true.) ! No error shown
+ call t(.true., 'comma', '4,4 ,', .true.) ! /!\ gfortran: error; others: no error
+ call t(.true., 'point', '4.4 ,', .true.) ! No error shown
+ call t(.true., 'comma', '4,4 ;', .true.) ! No error shown
+ call t(.true., 'point', '4.4 ;', .true.) ! No error shown
+
+! print *, '---------------'
+
+ call t(.true., 'comma', '8', .true.)
+ call t(.true., 'point', '8', .true.)
+ call t(.true., 'point', '9 ;', .true.)
+ call t(.true., 'comma', '3;3.', .true.)
+ call t(.true., 'point', '3,3.', .true.)
+ call t(.true., 'comma', '3;3,', .true.)
+ call t(.true., 'comma', '3;3;', .true.)
+ call t(.true., 'point', '3,3;', .true.)
+ call t(.true., 'comma', '4;4 .', .true.)
+ call t(.true., 'point', '4,4 .', .true.)
+ call t(.true., 'comma', '4;4 ,', .true.)
+ call t(.true., 'point', '4,4 ,', .true.)
+ call t(.true., 'comma', '4;4 ;', .true.)
+ call t(.true., 'point', '4,4 ;', .true.)
+
+ call t2('comma', ',2')
+ call t2('point', '.2')
+ call t2('comma', ',2;')
+ call t2('point', '.2,')
+ call t2('comma', ',2 ,')
+ call t2('point', '.2 .')
+contains
+subroutine t2(dec, testinput)
+ character(*) :: dec, testinput
+ integer ios
+ real :: r
+ r = 42
+ read(testinput,*,decimal=dec, iostat=ios) r
+ if (ios /= 0 .or. abs(r - 0.2) > epsilon(r)) then
+ stop 3
+ end if
+end
+subroutine t(valid, dec, testinput, isreal)
+ logical, value :: valid
+ character(len=*) :: dec, testinput
+ logical, optional :: isreal
+ logical :: isreal2
+ integer n,ios
+ real :: r
+ r = 42; n = 42
+ isreal2 = .false.
+ if (present(isreal)) isreal2 = isreal
+
+ if (isreal2) then
+ read(testinput,*,decimal=dec,iostat=ios) r
+ if ((valid .and. ios /= 0) .or. (.not.valid .and. ios == 0)) then
+ stop 1
+ end if
+ else
+ read(testinput,*,decimal=dec,iostat=ios) n
+ if ((valid .and. ios /= 0) .or. (.not.valid .and. ios == 0)) then
+ stop 1
+ end if
+ end if
+end
+end program