Created attachment 28553 [details] Source code
Created attachment 28554 [details] Namelist
$ gfortran bat.F90 $ ./a.out At line 33 of file bat.F90 (unit = 4, file = 'NAMELIST') Fortran runtime error: Internal namelist read error I tried 4.6.1, 4.6.2 and latest snapshot of 4.7. All the same.
I can confirm that I see the error with 4.3, 4.7 and trunk. Slightly reduced test case: *************************** IMPLICIT NONE TYPE TC INTEGER :: E END TYPE TYPE TB TYPE(TC) :: C INTEGER :: D END TYPE INTEGER :: A TYPE(TB) :: B(1:10) NAMELIST /N/ A, B OPEN (4,FILE='NAMELIST') READ (4,NML=N) END *************************** &N A=12, B(1)%D=4 / *************************** What's funny is that the error e.g. depends on the presence of the component 'C', although it is not referenced in the namelist at all. Furthermore the error only occurs if 'A' is also in the namelist.
Related to bugs: PR 49791 and PR 51825?
Adding myself to the CC list. Walter Spector
Another manifestation of this problem is with type extension. Here is another small example which fails. (Tested on v4.6.3 and also a 1/4/2013 snapshot of the 4.8 trunk.): program test_type_extension type t1_t real :: x end type t1_t type, extends(t1_t) :: t1e_t character(8) :: string end type t1e_t type(t1e_t) :: t1e integer :: answer namelist /test_NML/ t1e, answer open(unit=1,file='test1.inp') read(1,NML=test_NML) write(*,*) t1e%x, t1e%string, answer end program test_type_extension File test1.inp contains: &test_NML t1e%x = 2.,t1e%string='gfortran',answer=42 / wws@w6ws-4:~/fortran/xxx$ gfortran --version GNU Fortran (GCC) 4.8.0 20130104 (experimental) Copyright (C) 2013 Free Software Foundation, Inc. GNU Fortran comes with NO WARRANTY, to the extent permitted by law. You may redistribute copies of GNU Fortran under the terms of the GNU General Public License. For more information about these matters, see the file named COPYING wws@w6ws-4:~/fortran/xxx$ gfortran namelist.f90 wws@w6ws-4:~/fortran/xxx$ a.out At line 17 of file namelist.f90 (unit = 1, file = 'test1.inp') Fortran runtime error: Cannot match namelist object name %x Backtrace for this error: + in the main program from file namelist.f90 + /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed) [0x7ffe80c5376d] wws@w6ws-4:~/fortran/xxx$ The NAG Fortran compiler has no problems with this test case. (Intel and PGI are not so lucky. :) )
(In reply to comment #6) > Another manifestation of this problem is with type extension. Here is another > small example which fails. (Tested on v4.6.3 and also a 1/4/2013 snapshot of > the 4.8 trunk.): > > program test_type_extension > > type t1_t > real :: x > end type t1_t > > type, extends(t1_t) :: t1e_t > character(8) :: string > end type t1e_t > > type(t1e_t) :: t1e > > integer :: answer > namelist /test_NML/ t1e, answer > > open(unit=1,file='test1.inp') > read(1,NML=test_NML) > > write(*,*) t1e%x, t1e%string, answer > > end program test_type_extension > > File test1.inp contains: > > &test_NML > t1e%x = 2.,t1e%string='gfortran',answer=42 > / > > wws@w6ws-4:~/fortran/xxx$ gfortran namelist.f90 > wws@w6ws-4:~/fortran/xxx$ a.out > At line 17 of file namelist.f90 (unit = 1, file = 'test1.inp') > Fortran runtime error: Cannot match namelist object name %x If one modifies your code to have gfortran create the file with the namelist, it can then read it back. Here's what I have program test_type_extension type t1_t real :: x end type t1_t type, extends(t1_t) :: t1e_t character(8) :: string end type t1e_t type(t1e_t) :: t1e integer :: answer namelist /test_NML/ t1e, answer t1e%x = 2. t1e%string='gfortran' answer=42 open(unit=2,file='test2.inp') write(2,NML=test_NML) close(2) t1e%x = 0 t1e%string='' answer=0 open(unit=2,file='test2.inp') read(2,NML=test_NML) close(2) write(*,*) t1e%x, t1e%string, answer open(unit=1,file='test1.inp') read(1,NML=test_NML) write(*,*) t1e%x, t1e%string, answer end program test_type_extension % gfc4x -o z foo.f90 && ./z 2.00000000 gfortran 42 At line 36 of file foo.f90 (unit = 1, file = 'test1.inp') Fortran runtime error: Cannot match namelist object name %x % cat test2.inp &TEST_NML T1E%T1_T%X= 2.00000000 , T1E%STRING="gfortran", ANSWER= 42, / It appears that gfortran's handling of an extended derived type in its namelist code is incorrect.
Good point. The key is: > T1E%T1_T%X= 2.00000000 , If the full expanded version is used, in other words %T1_T is specified, the example works. (On Intel too.)
I am actively working on these bugs right now so will assign to myself. Our namelist code here is tricky to say the least and i am seeing odd behavior that looks like some pointers are not getting set or reset correctly. If I get to a patch, I will post here.
This bug appears to be unrelated to the other two namelist bugs. It is related to not seeing the ending '/' marker. I have more testing to go before submitting a patch. The initial fix is to catch it in the do loop inside list_read.c at about line 2812. I still need to confirm if the reads are actually correct.
Hi, I ran into this today and tried to produce a small test case from my big namelist problem. program namelist type d1 integer :: j = 0 end type d1 type d2 type(d1) k end type d2 type d3 type(d2) d(2) end type d3 type(d3) der namelist /nmlst/ der read (*, nml = nmlst) print nmlst end program namelist Running above program on all two line combinations of the namelist gives different errors using 4.7.2 and gcc version 4.8.0 20130222 (experimental) (GCC) (Details below). Observations: - If type d3 uses 'type(d1) d(2)' instead of 'type(d2) d(2)', the problem goes away. - If the trailing %J is removed in the namelist, the problem goes away. - If two separate members are used instead of the array 'type(d2) d(2)', the problem goes away. Details of namelist variations: % cat namelist.txt; echo -------; prg_namelist_bug < namelist.txt &NMLST / ------- &NMLST DER%D(1)%K%J= 0, DER%D(2)%K%J= 0, / % cat namelist.txt; echo -------; prg_namelist_bug < namelist.txt &NMLST DER%D(1)%K%J = 1, / ------- &NMLST DER%D(1)%K%J= 1, DER%D(2)%K%J= 0, / % cat namelist.txt; echo -------; prg_namelist_bug < namelist.txt &NMLST DER%D(2)%K%J = 2, / ------- &NMLST DER%D(1)%K%J= 2, DER%D(2)%K%J= 0, / % cat namelist.txt; echo -------; prg_namelist_bug < namelist.txt &NMLST DER%D(1)%K%J = 1, DER%D(2)%K%J = 2, / ------- &NMLST DER%D(1)%K%J= 2, DER%D(2)%K%J= 0, / % cat namelist.txt; echo -------; prg_namelist_bug < namelist.txt &NMLST DER%D(2)%K%J = 2, DER%D(1)%K%J = 1, / ------- &NMLST DER%D(1)%K%J= 1, DER%D(2)%K%J= 0, / If the last component %J is removed in the namelist, the problem goes away: % cat namelist.txt; echo -------; prg_namelist_bug < namelist.txt &NMLST DER%D(1)%K = 1, / ------- &NMLST DER%D(1)%K%J= 1, DER%D(2)%K%J= 0, / % cat namelist.txt; echo -------; prg_namelist_bug < namelist.txt &NMLST DER%D(2)%K = 2, / ------- &NMLST DER%D(1)%K%J= 0, DER%D(2)%K%J= 2, / % cat namelist.txt; echo -------; prg_namelist_bug < namelist.txt &NMLST DER%D(1)%K = 1, DER%D(2)%K = 2, / ------- &NMLST DER%D(1)%K%J= 1, DER%D(2)%K%J= 2, / % cat namelist.txt; echo -------; prg_namelist_bug < namelist.txt &NMLST DER%D(2)%K = 2, DER%D(1)%K = 1, / ------- &NMLST DER%D(1)%K%J= 1, DER%D(2)%K%J= 2, / Regards, Tilo
(In reply to comment #11) > Running above program on all two line combinations of the namelist gives > different errors using > 4.7.2 and > gcc version 4.8.0 20130222 (experimental) (GCC) > (Details below). What I meant here was, that the namelist variations give different errors, not that 4.7.2 and 4.8.0 give different errors. Tilo
If in gfortran.dg/namelist_64.f90 instead of curve(1)%symbol%typee = 1234 any other array index > 1 is set and tested, e.g. curve(2)%symbol%typee = 1234 the testcase breaks.
Created attachment 29532 [details] Namelist patch
This week I used the Fortran namelist feature for the first time and I was really impressed, that it does all the parsing for me. But since I ran into this issue I was wondering and curious how the magic in libgfortran works. I had a look at the code and could observe the following: If I apply the attached patch (comment 14, namelist.diff) on gcc version 4.8.0 20130224 - my example from comment 11 works - the example from comment 3 seems to work - the changed namelist_64.f90 from comment 13 works - the example from PR 51825 seems to work - make check-fortran runs with no additional errors - the example from comment 6 (type extension) does not work The type extension problem might be related to the fact, that gfortran does not generate a namelist entry for the implicit component %x of t1e_t: (no "t1e%x" below) _gfortran_st_set_nml_var (&dt_parm.1, &t1e, &"t1e"[1]{lb: 1 sz: 1}, 0, 0, 40); ... maybe "t1e%x" should be here? ... _gfortran_st_set_nml_var (&dt_parm.1, &t1e.t1_t, &"t1e%t1_t"[1]{lb: 1 sz: 1}, 0, 0, 40); _gfortran_st_set_nml_var (&dt_parm.1, &t1e.t1_t.x, &"t1e%t1_t%x"[1]{lb: 1 sz: 1}, 4, 0, 24); _gfortran_st_set_nml_var (&dt_parm.1, &t1e.string, &"t1e%string"[1]{lb: 1 sz: 1}, 1, 8, 48); _gfortran_st_set_nml_var (&dt_parm.1, &answer, &"answer"[1]{lb: 1 sz: 1}, 4, 0, 8); So maybe this patch gives a hint to someone, who has a deeper understanding of the io-stuff than me (looked at it this weekend for the first time) ... Tilo
(In reply to comment #14) > Created attachment 29532 [details] > Namelist patch Bummer, I had a typo in the comment: The second hunk should read "/* Don't move first_nl" instead of "/* Don't move pprev_nl": @@ -2901,7 +2901,8 @@ get_name: goto nml_err_ret; } - if (*pprev_nl == NULL || !component_flag) + /* Don't move first_nl further in the list if a qualifier was found */ + if ((*pprev_nl == NULL && !qualifier_flag) || !component_flag) first_nl = nl; Sorry, Tilo
(In reply to comment #15) > The type extension problem might be related to the fact, that gfortran does not > generate a namelist entry for the implicit component %x of t1e_t: > > (no "t1e%x" below) > It is present... > _gfortran_st_set_nml_var (&dt_parm.1, &t1e.t1_t.x, &"t1e%t1_t%x"[1]{lb: 1 sz: > 1}, 4, 0, 24); > ... here.
(In reply to comment #17) > (In reply to comment #15) > > The type extension problem might be related to the fact, that gfortran does not > > generate a namelist entry for the implicit component %x of t1e_t: > > > > (no "t1e%x" below) > > > It is present... > > > _gfortran_st_set_nml_var (&dt_parm.1, &t1e.t1_t.x, &"t1e%t1_t%x"[1]{lb: 1 sz: > > 1}, 4, 0, 24); > > > ... here. Yes, somehow - but the code in list_read.c:find_nml_node() (as it is right now) searches for the exact string "t1e%x", not for "t1e%t1_t%x". I have no idea what is simpler: - modify the code in list_read.c to somehow also search "t1e%t1_t%x", not only "t1e%x". Maybe one could teach the code to conclude from the to namelist entries _gfortran_st_set_nml_var (&dt_parm.1, &t1e.t1_t, &"t1e%t1_t"... _gfortran_st_set_nml_var (&dt_parm.1, &t1e.t1_t.x, &"t1e%t1_t%x" that "t1e%x" is also valid a synonym of "t1e%t1_t%x". or - generate a line like _gfortran_st_set_nml_var (&dt_parm.1, &t1e.t1_t.x, &"t1e%x" ...
The issue of the original bug report in comment 0 - and the test cases comment 3 and comment 13 seem to be fixed by the patch for PR 51825 (see PR 51825 comment 5). Remaining seems to be the separate issue of type extension, where the parent's component is directly accessed without using the parent's name as in-between component name. See comment 6.
Lets take namelist out of the picture here for the case of comment #6 program test_type_extension type t1_t real :: x end type t1_t type, extends(t1_t) :: t1e_t character(8) :: string end type t1e_t type(t1e_t) :: t1e tle%x = 5.678 end program test_type_extension $ gfc pr55117.f90 pr55117.f90:13.6: tle%x = 5.678 1 Error: Symbol 'tle' at (1) has no IMPLICIT type Ifort agrees with gfortran on this example So, I think this PR (55117) can be closed and if the example in this comment and #6 is another bug, lets open a new PR for it.
Oops! Disregard Comment #20. There is a not so subtle effect when one mixes up the letter 'l' and the digit '1' in names.
Created attachment 29938 [details] FE patch for namelist read with type extension (+ test case) Regarding the support of type extension: This patch uses in the front end a "+" instead of a "%" to denote a type extension, i.e. type%parent%var becomes type+parent%var in the call to st_set_nml_var. Then, libgfortran has the required information - the actual implementation is still pending.
> Created attachment 29938 [details] > FE patch for namelist read with type extension (+ test case) What happened to this patch?
I am currently working with Tobias FE patch and modifying the library side now.
Preliminary patch here: http://gcc.gnu.org/ml/fortran/2014-03/msg00150.html
Author: jvdelisle Date: Mon May 26 15:19:36 2014 New Revision: 210934 URL: http://gcc.gnu.org/viewcvs?rev=210934&root=gcc&view=rev Log: 2014-05-26 Tobias Burnus <burnus@net-b.de> PR fortran/55117 * trans-io.c (nml_full_name, transfer_namelist_element): Insert a '+' rather then '%' to differentiate namelist variable names that are based on extended derived types. 2014-05-26 Jerry DeLisle <jvdelisle@gcc.gnu.org> PR libgfortran/55117 * io/list_read.c (extended_look_ahead): New helper function to scan the namelist name and look for matches with the new '+' extended type parent indicator. (str_comp_extended): New helper function to compare the namelist name with the varname namelist. (find_nml_name): Use the new helper functions to match the extended type varnames. Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/trans-io.c trunk/libgfortran/ChangeLog trunk/libgfortran/io/list_read.c
Author: jvdelisle Date: Mon May 26 15:32:33 2014 New Revision: 210935 URL: http://gcc.gnu.org/viewcvs?rev=210935&root=gcc&view=rev Log: 2014-05-26 Jerry DeLisle <jvdelisle@gcc.gnu.org> PR libgfortran/55117 * gfortran.dg/namelist_85.f90: New test. Added: trunk/gcc/testsuite/gfortran.dg/namelist_85.f90 Modified: trunk/gcc/testsuite/ChangeLog
Fixed on Trunk, closing
Missed the button.