When I compile the following module: module datetime_mod implicit none private save type, public :: DateTime integer :: year = 0, month = 0, day = 0, hh = 0, mm = 0, ss = 0, & sss = 0 contains procedure :: getString procedure :: getDateString procedure :: getTimeString procedure, private :: getFormattedString end type type(DateTime), parameter :: & !*** ISO_REFERENCE_DATE = DateTime(1875, 5, 20, 0, 0, 0, 0), & !*** GREGORIAN_REFERENCE_DATE = DateTime(1582, 10, 15, 0, 0, 0, 0) !*** contains function getString(dt, FMT) result(string) character(:), allocatable :: string class(DateTime), intent(IN) :: dt integer, optional, intent(IN) :: FMT continue string = dt%getFormattedString(0, FMT) end function function getDateString(dt, FMT) result(string) character(:), allocatable :: string class(DateTime), intent(IN) :: dt integer, optional, intent(IN) :: FMT continue string = dt%getFormattedString(1, FMT) end function function getTimeString(dt, FMT) result(string) character(:), allocatable :: string class(DateTime), intent(IN) :: dt integer, optional, intent(IN) :: FMT continue string = dt%getFormattedString(2, FMT) end function elemental function getFormattedString(this, FILTER, FMT) & result(string) character(:), allocatable :: string class(DateTime), intent(IN) :: this integer, optional, intent(IN) :: FILTER, FMT continue string = '' end function end module datetime_mod gfortran does not recognize getFormattedString as a type-bound procedure. There are also errors related to the use of a deferred-length character as a function result (reported as Bug 49110), and an unnecessary warning about the duplicate save attribute. The exact output is: ...:~$ gfortran -c test_gfortran_missing_tbp.f90 test_gfortran_missing_tbp.f90:27.38: string = dt%getFormattedString(0, FMT) 1 Error: 'getformattedstring' at (1) is not a member of the 'datetime' structure test_gfortran_missing_tbp.f90:35.38: string = dt%getFormattedString(1, FMT) 1 Error: 'getformattedstring' at (1) is not a member of the 'datetime' structure test_gfortran_missing_tbp.f90:43.38: string = dt%getFormattedString(2, FMT) 1 Error: 'getformattedstring' at (1) is not a member of the 'datetime' structure test_gfortran_missing_tbp.f90:46.4: elemental function getFormattedString(dt, FILTER, FMT) & 1 Error: CHARACTER(*) function 'getformattedstring' at (1) cannot be pure test_gfortran_missing_tbp.f90:46.4: elemental function getFormattedString(dt, FILTER, FMT) & 1 Error: CHARACTER(*) function 'getformattedstring' at (1) cannot be pure test_gfortran_missing_tbp.f90:46.4: elemental function getFormattedString(dt, FILTER, FMT) & 1 Error: CHARACTER(*) function 'getformattedstring' at (1) cannot be pure test_gfortran_missing_tbp.f90:18.62: ISO_REFERENCE_DATE = DateTime(1875, 5, 20, 0, 0, 0, 0), & !*** 1 Warning: Duplicate SAVE attribute specified at (1) test_gfortran_missing_tbp.f90:18.62: ISO_REFERENCE_DATE = DateTime(1875, 5, 20, 0, 0, 0, 0), & !*** 1 Warning: Duplicate SAVE attribute specified at (1) If I remove the three lines marked with "!***" and also remove the ELEMENTAL attribute from the getFormattedString function, and compile again, then I get an internal compiler error: ...:~$ gfortran -c test_gfortran_ice.f90 test_gfortran_ice.f90:20.41: class(DateTime), intent(IN) :: dt 1 Warning: Duplicate SAVE attribute specified at (1) test_gfortran_ice.f90:20.41: class(DateTime), intent(IN) :: dt 1 Warning: Duplicate SAVE attribute specified at (1) test_gfortran_ice.f90: In function ‘gettimestring’: test_gfortran_ice.f90:41:0: internal compiler error: in fold_convert_loc, at fold-const.c:1906 Please submit a full bug report, with preprocessed source if appropriate. See <file:///usr/share/doc/gcc-4.6/README.Bugs> for instructions The version information is: ...:~$ gfortran -v Using built-in specs. COLLECT_GCC=gfortran COLLECT_LTO_WRAPPER=/usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.6.1/lto-wrapper Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.6.0-3~ppa1' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++,go --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-multiarch --with-multiarch-defaults=x86_64-linux-gnu --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib/x86_64-linux-gnu --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib/x86_64-linux-gnu --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 4.6.1 20110409 (prerelease) (Ubuntu 4.6.0-3~ppa1) The system information (for Ubuntu 11.04) is: ...:~$ uname -srvmpio Linux 2.6.38-8-generic #42-Ubuntu SMP Mon Apr 11 03:31:24 UTC 2011 x86_64 x86_64 x86_64 GNU/Linux
Created attachment 24329 [details] Test case
Created attachment 24330 [details] Test case for ICE
(In reply to comment #0) > ...:~$ gfortran -c test_gfortran_ice.f90 > test_gfortran_ice.f90:20.41: > > class(DateTime), intent(IN) :: dt > 1 > Warning: Duplicate SAVE attribute specified at (1) > test_gfortran_ice.f90:20.41: > > class(DateTime), intent(IN) :: dt > 1 > Warning: Duplicate SAVE attribute specified at (1) Here is a reduced test case for the duplicate SAVE attribute: module datetime_mod implicit none save type :: DateTime end type contains character function getString (dt) class(DateTime) :: dt end function end module At first glance I would save this is invalid, and should be rejected with an error. In particular, is it allowed to give a lonely SAVE statement? If yes, what effect should this have? Usually SAVE is specified as an attribute for a specific variable, right?
(In reply to comment #3) > (In reply to comment #0) > > ...:~$ gfortran -c test_gfortran_ice.f90 > > test_gfortran_ice.f90:20.41: > > > > class(DateTime), intent(IN) :: dt > > 1 > > Warning: Duplicate SAVE attribute specified at (1) > > test_gfortran_ice.f90:20.41: > > > > class(DateTime), intent(IN) :: dt > > 1 > > Warning: Duplicate SAVE attribute specified at (1) > > > Here is a reduced test case for the duplicate SAVE attribute: > > > module datetime_mod > > implicit none > save > > type :: DateTime > end type > > contains > > character function getString (dt) > class(DateTime) :: dt > end function > > end module > > > At first glance I would save this is invalid, and should be rejected with an > error. In particular, is it allowed to give a lonely SAVE statement? If yes, > what effect should this have? Usually SAVE is specified as an attribute for a > specific variable, right? SAVE can be either a statement or an attribute. When it's statement, it affects all the variables within the containing unit (e.g., in the case of a module, it affects all the variables declared before the "contains"). When it's the attribute for a particular variable declaration, it affects the variable only. Since in Fortran initialization implies SAVE, and the ISO_REFERENCE_DATE is being (sort of) initialized, the compiler is assuming a duplicate SAVE. The standard also allows the confirmation, as an attribute, of the SAVE at the module level, so, for a "triple save" example: module t1_mod save type :: t1 integer :: dummy = 0 end type type(t1), save :: a = t1(2), b = t1(3) end type Which also triggers a duplicate save warning.
(In reply to comment #4) > SAVE can be either a statement or an attribute. When it's statement, it > affects all the variables within the containing unit Yes, of course. I completely forgot about this possibility. Btw, the code in comment #3 works with gfortran 4.5, so it is in fact a regression. > The standard also allows the confirmation, as an attribute, of the SAVE at the > module level, so, for a "triple save" example: > > module t1_mod > save > > type :: t1 > integer :: dummy = 0 > end type > > type(t1), save :: a = t1(2), b = t1(3) > end type > > > Which also triggers a duplicate save warning. This is at best a "double save", and I think the (F08) standard forbids it: C580 (R553) If a SAVE statement with an omitted saved entity list appears in a scoping unit, no other appearance of the SAVE attr-spec or SAVE statement is permitted in that scoping unit. So I think in this case gfortran correctly complains about a "Duplicate SAVE attribute".
(In reply to comment #0) > ...:~$ gfortran -c test_gfortran_missing_tbp.f90 > test_gfortran_missing_tbp.f90:27.38: > > string = dt%getFormattedString(0, FMT) > 1 > Error: 'getformattedstring' at (1) is not a member of the 'datetime' structure Here is a reduced test case for this error, which is also a regression: module datetime_mod implicit none type :: DateTime integer :: year, month, day contains procedure :: getFormattedString end type type(DateTime) :: ISO_REFERENCE_DATE = DateTime(1875, 5, 20) contains character function getString(dt) class(DateTime) :: dt getString = dt%getFormattedString() end function character function getFormattedString(dt) class(DateTime) :: dt end function end module
Here is a reduced test case for the ICE: module datetime_mod implicit none private type :: DateTime contains procedure :: getFormattedString end type contains function getTimeString(dt, FMT) result(string) character(:), allocatable :: string class(DateTime), intent(IN) :: dt integer, optional, intent(IN) :: FMT string = dt%getFormattedString(2, FMT) end function function getFormattedString(this, FILTER, FMT) & result(string) character(:), allocatable :: string class(DateTime), intent(IN) :: this integer, optional, intent(IN) :: FILTER, FMT end function end module
(In reply to comment #5) > (In reply to comment #4) > > SAVE can be either a statement or an attribute. When it's statement, it > > affects all the variables within the containing unit > > Yes, of course. I completely forgot about this possibility. > > Btw, the code in comment #3 works with gfortran 4.5, so it is in fact a > regression. > > > > The standard also allows the confirmation, as an attribute, of the SAVE at the > > module level, so, for a "triple save" example: > > > > module t1_mod > > save > > > > type :: t1 > > integer :: dummy = 0 > > end type > > > > type(t1), save :: a = t1(2), b = t1(3) > > end type Sorry, it should have been "end module" > > > > > > Which also triggers a duplicate save warning. > > This is at best a "double save", and I think the (F08) standard forbids it: > > C580 (R553) If a SAVE statement with an omitted saved entity list appears in a > scoping unit, no other appearance of the SAVE attr-spec or SAVE statement is > permitted in that scoping unit. > t > So I think in this case gfortran correctly complains about a "Duplicate SAVE > attribute". Ups... I completely forgot about that constraint (I must have been thinking about section 5.3.16, which mentions an implicit SAVE statement for modules, and that one can be explicitly confirmed). So yes, it's at best an extension to the standard. Intel's and Sun's compilers complain about it: ...:~$ ifort -stand -c t1.f90 t1.f90(8): warning #7652: The F2003 standard says that the SAVE attribute is invalid since there is an occurrence of a SAVE statement with an omitted save-entity-list in the same scoping unit. [SAVE] type(t1), save :: a = t1(2), b = t1(3) ...:~$ sunf95 -ansi -c t1.f90 type(t1), save :: a = t1(2), b = t1(3) ^ "t1.f90", Line = 8, Column = 15: ANSI: The Fortran standard requires a SAVE statement with no saved-entity-list to be the only SAVE in the scoping unit. One thing about the original code, is that the "duplicate save" warning is being issued for an entity with the PARAMETER attribute ---so the SAVE at the scoping unit shouldn't even affect it, since the entity is not really a variable.
(In reply to comment #3) > Here is a reduced test case for the duplicate SAVE attribute: The duplicate SAVE warning of comment #3 can be fixed with something like this: Index: gcc/fortran/symbol.c =================================================================== --- gcc/fortran/symbol.c (revision 174416) +++ gcc/fortran/symbol.c (working copy) @@ -3400,7 +3400,8 @@ save_symbol (gfc_symbol *sym) if (sym->attr.in_common || sym->attr.dummy || sym->attr.result - || sym->attr.flavor != FL_VARIABLE) + || sym->attr.flavor != FL_VARIABLE + || (sym->name[0]=='_' && sym->name[1]=='_')) return; /* Automatic objects are not saved. */ if (gfc_is_var_automatic (sym)) This prevents 'internal' symbols, starting with '__', from getting a SAVE attribute twice.
(In reply to comment #6) > > > > string = dt%getFormattedString(0, FMT) > > 1 > > Error: 'getformattedstring' at (1) is not a member of the 'datetime' structure > > Here is a reduced test case for this error, which is also a regression: ... probably due to my r163631: http://gcc.gnu.org/viewcvs?view=revision&revision=163631 It can be fixed by this partial revert: =================================================================== --- gcc/fortran/resolve.c (revision 174415) +++ gcc/fortran/resolve.c (working copy) @@ -964,9 +964,6 @@ resolve_structure_cons (gfc_expr *expr, int init) t = SUCCESS; - if (expr->ts.type == BT_DERIVED) - resolve_symbol (expr->ts.u.derived); - cons = gfc_constructor_first (expr->value.constructor); /* A constructor may have references if it is the result of substituting a parameter variable. In this case we just pull out the component we
(In reply to comment #10) > It can be fixed by this partial revert: > > =================================================================== > --- gcc/fortran/resolve.c (revision 174415) > +++ gcc/fortran/resolve.c (working copy) > @@ -964,9 +964,6 @@ resolve_structure_cons (gfc_expr *expr, int init) > > t = SUCCESS; > > - if (expr->ts.type == BT_DERIVED) > - resolve_symbol (expr->ts.u.derived); > - > cons = gfc_constructor_first (expr->value.constructor); > /* A constructor may have references if it is the result of substituting a > parameter variable. In this case we just pull out the component we Unfortunately this patchlet seems to induce the following testsuite regressions: FAIL: gfortran.dg/func_assign_3.f90 -O0 (test for excess errors) FAIL: gfortran.dg/func_result_6.f90 -O0 (test for excess errors) FAIL: gfortran.dg/typebound_call_7.f03 -O (test for excess errors) FAIL: gfortran.dg/typebound_call_8.f03 -O (test for excess errors) The patch in comment #9, however, seems to be clean.
Author: janus Date: Tue Jun 21 12:12:51 2011 New Revision: 175257 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=175257 Log: 2011-06-21 Janus Weil <janus@gcc.gnu.org> PR fortran/49112 * class.c (gfc_find_derived_vtab): Make vtab and default initialization symbols SAVE_IMPLICIT. 2011-06-21 Janus Weil <janus@gcc.gnu.org> PR fortran/49112 * gfortran.dg/class_44.f03: New. Added: trunk/gcc/testsuite/gfortran.dg/class_44.f03 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/class.c trunk/gcc/testsuite/ChangeLog
Author: janus Date: Tue Jun 21 12:20:28 2011 New Revision: 175259 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=175259 Log: 2011-06-21 Janus Weil <janus@gcc.gnu.org> PR fortran/49112 * class.c (gfc_find_derived_vtab): Make vtab and default initialization symbols SAVE_IMPLICIT. 2011-06-21 Janus Weil <janus@gcc.gnu.org> PR fortran/49112 * gfortran.dg/class_44.f03: New. Added: branches/gcc-4_6-branch/gcc/testsuite/gfortran.dg/class_44.f03 Modified: branches/gcc-4_6-branch/gcc/fortran/ChangeLog branches/gcc-4_6-branch/gcc/fortran/class.c branches/gcc-4_6-branch/gcc/testsuite/ChangeLog
The "duplicate save" regression is fixed on trunk and 4.6. Remaining problems: 1) The structure constructor regression in comment #6. 2) The ICE in comment #7.
GCC 4.6.1 is being released.
(In reply to comment #14) > The "duplicate save" regression is fixed on trunk and 4.6. Remaining problems: > > 1) The structure constructor regression in comment #6. > 2) The ICE in comment #7. The latter is tracked by the related PR49430, so for this PR only the regression in comment #6 is left to fix.
Janus, this regression (comment 6 remains to be done) is assigned to you. Are you still working on it?
(In reply to comment #17) > Janus, this regression (comment 6 remains to be done) is assigned to you. Are > you still working on it? Well, at least it's on my (unfortunately long) to-do list. I'll try to find some time for it on the weekend. After all it seems like I'm the one who is to blame for this regression, cf. comment #10 and #11.
Author: janus Date: Sun Jul 31 10:25:07 2011 New Revision: 176971 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=176971 Log: 2011-07-31 Janus Weil <janus@gcc.gnu.org> PR fortran/49112 * resolve.c (resolve_structure_cons): Don't do the full dt resolution, only call 'resolve_fl_derived0'. (resolve_typebound_procedures): Resolve typebound procedures of parent type. (resolve_fl_derived0): New function, which does a part of the work for 'resolve_fl_derived'. (resolve_fl_derived): Call 'resolve_fl_derived0' and do some additional things. 2011-07-31 Janus Weil <janus@gcc.gnu.org> PR fortran/49112 * gfortran.dg/abstract_type_6.f03: Modified. * gfortran.dg/typebound_proc_24.f03: New. Added: trunk/gcc/testsuite/gfortran.dg/typebound_proc_24.f03 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/resolve.c trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gfortran.dg/abstract_type_6.f03
Author: janus Date: Fri Aug 5 17:03:50 2011 New Revision: 177468 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=177468 Log: 2011-08-05 Janus Weil <janus@gcc.gnu.org> PR fortran/49112 * resolve.c (resolve_structure_cons): Don't do the full dt resolution, only call 'resolve_fl_derived0'. (resolve_typebound_procedures): Resolve typebound procedures of parent type. (resolve_fl_derived0): New function, which does a part of the work for 'resolve_fl_derived'. (resolve_fl_derived): Call 'resolve_fl_derived0' and do some additional things. 2011-08-05 Janus Weil <janus@gcc.gnu.org> PR fortran/49112 * gfortran.dg/abstract_type_6.f03: Modified. * gfortran.dg/typebound_proc_24.f03: New. Added: branches/gcc-4_6-branch/gcc/testsuite/gfortran.dg/typebound_proc_24.f03 Modified: branches/gcc-4_6-branch/gcc/fortran/ChangeLog branches/gcc-4_6-branch/gcc/fortran/resolve.c branches/gcc-4_6-branch/gcc/testsuite/ChangeLog branches/gcc-4_6-branch/gcc/testsuite/gfortran.dg/abstract_type_6.f03
The regression of comment #6 has been fixed on 4.6 and trunk. Since this was the last item in this PR, I'm closing it as fixed.