The following is a code snippet with an implicit save for the variable I. SUBROUTINE T() INTEGER :: I=1 WRITE(6,*) I I=I+1 END SUBROUTINE T CALL T() CALL T() END Expecting this code to print twice 1 is one of the common mistakes for (C) programmers starting with Fortran, see e.g. http://www.cs.rpi.edu/~szymansk/OOF90/bugs.html It would be nice if the compiler could optionally (-Wextra?) emit a warning for implicit save attributes. Obviously the explicit code 'INTEGER, SAVE :: I=1' should be fine.
Usual answer!
I have a quite common "counter example", where a subroutine is initialized on first invocation: subroutine foo () logical :: first = .true. write(6,*) first if (first) then first = .false. ! Do initialization end if end subroutine foo call foo () call foo () end Should this one also get a warning?
(In reply to Harald Anlauf from comment #2) > I have a quite common "counter example" > Should this one also get a warning? yes, while there are plenty of good uses of saved variables (really?), it should be made more explicit i.e. just write logical, save :: first = .true. as often with warnings, expert programmers won't need them, but novices might (and they are useful to enforce good coding style with -Werror=foo). It is certainly something I would add to the enforce list for our project.
*** Bug 102638 has been marked as a duplicate of this bug. ***
IMHO this should be a "surprising" warning when -Wsurprising is specified. The message should suggest adding an explicit SAVE attribute to make the code clear.
With this patch, diff --git a/gcc/fortran/decl.cc b/gcc/fortran/decl.cc index 503ecb8d9b5..abb3579893f 100644 --- a/gcc/fortran/decl.cc +++ b/gcc/fortran/decl.cc @@ -2278,7 +2278,12 @@ add_init_expr_to_sym (const char *name, gfc_expr **initp, locus *var_locus) sym->value = init; if (sym->attr.save == SAVE_NONE) - sym->attr.save = SAVE_IMPLICIT; + { + sym->attr.save = SAVE_IMPLICIT; + if (warn_surprising) + gfc_warning (OPT_Wsurprising, "Entity %qs at %L has an implicit " + "SAVE attribute", sym->name, &sym->declared_at); + } *initp = NULL; } I see % gfcx -o z a.f90 -Wsurprising && ./z a.f90:2:13: 2 | integer :: i=1 | 1 Warning: Entity ‘i’ at (1) has an implicit SAVE attribute [-Wsurprising] 1
Upon some additional thinking, I wonder how useful this will be compared to the possible volume of warning messages from modern Fortran. Consider this code: module foo integer :: j = 2 type a integer :: k = 3 end type type(a) :: b = a(4) integer, target :: n integer, pointer :: m => n end module foo subroutine t() integer :: i=1 write(6,*) i i=i+1 end subroutine t call t() call t() end with the patch at the end of this email, I see % gfcx -c -Wsurprising -Wall a.f90 a.f90:2:14: 2 | integer :: j = 2 | 1 Warning: Entity at (1) has an implicit SAVE attribute [-Wsurprising] a.f90:6:14: 6 | type(a) :: b = a(4) | 1 Warning: Entity at (1) has an implicit SAVE attribute [-Wsurprising] a.f90:7:22: 7 | integer, target :: n | 1 Warning: Entity at (1) has an implicit SAVE attribute [-Wsurprising] a.f90:8:23: 8 | integer, pointer :: m => n | 1 Warning: Entity at (1) has an implicit SAVE attribute [-Wsurprising] a.f90:12:13: 12 | integer :: i=1 | 1 Warning: ‘i’ at (1) has an implicit SAVE attribute [-Wsurprising] diff --git a/gcc/fortran/decl.cc b/gcc/fortran/decl.cc index 503ecb8d9b5..d6ef37e51f2 100644 --- a/gcc/fortran/decl.cc +++ b/gcc/fortran/decl.cc @@ -2278,7 +2278,12 @@ add_init_expr_to_sym (const char *name, gfc_expr **initp, locus *var_locus) sym->value = init; if (sym->attr.save == SAVE_NONE) - sym->attr.save = SAVE_IMPLICIT; + { + sym->attr.save = SAVE_IMPLICIT; + if (warn_surprising) + gfc_warning (OPT_Wsurprising, "%qs at %L has an implicit SAVE " + "attribute", sym->name, &sym->declared_at); + } *initp = NULL; } @@ -5868,7 +5873,12 @@ match_attr_spec (void) || gfc_current_state () == COMP_SUBMODULE) && !current_attr.save && (gfc_option.allow_std & GFC_STD_F2008) != 0) - current_attr.save = SAVE_IMPLICIT; + { + current_attr.save = SAVE_IMPLICIT; + if (warn_surprising) + gfc_warning (OPT_Wsurprising, "Entity at %C has an implicit SAVE " + "attribute"); + } colon_seen = 1; return MATCH_YES;
Hi, It is a good point. The message is helpful when issued within a procedure. At module scope, it doesn't mean much since everything at that level is SAVE anyway. This is similar to what happens in C: int x = 3; // statically allocated void fn () { int i=3; // stack allocated } Walter -----Original Message----- From: kargl at gcc dot gnu.org <gcc-bugzilla@gcc.gnu.org> Sent: Jan 21, 2024 9:43 AM To: <w6ws@earthlink.net> Subject: [Bug fortran/57360] Implement a warning for implied save https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57360 --- Comment #7 from kargl at gcc dot gnu.org --- Upon some additional thinking, I wonder how useful this will be compared to the possible volume of warning messages from modern Fortran. Consider this code: module foo integer :: j = 2 type a integer :: k = 3 end type type(a) :: b = a(4) integer, target :: n integer, pointer :: m => n end module foo subroutine t() integer :: i=1 write(6,*) i i=i+1 end subroutine t call t() call t() end with the patch at the end of this email, I see % gfcx -c -Wsurprising -Wall a.f90 a.f90:2:14: 2 | integer :: j = 2 | 1 Warning: Entity at (1) has an implicit SAVE attribute [-Wsurprising] a.f90:6:14: 6 | type(a) :: b = a(4) | 1 Warning: Entity at (1) has an implicit SAVE attribute [-Wsurprising] a.f90:7:22: 7 | integer, target :: n | 1 Warning: Entity at (1) has an implicit SAVE attribute [-Wsurprising] a.f90:8:23: 8 | integer, pointer :: m => n | 1 Warning: Entity at (1) has an implicit SAVE attribute [-Wsurprising] a.f90:12:13: 12 | integer :: i=1 | 1 Warning: ‘i’ at (1) has an implicit SAVE attribute [-Wsurprising] diff --git a/gcc/fortran/decl.cc b/gcc/fortran/decl.cc index 503ecb8d9b5..d6ef37e51f2 100644 --- a/gcc/fortran/decl.cc +++ b/gcc/fortran/decl.cc @@ -2278,7 +2278,12 @@ add_init_expr_to_sym (const char *name, gfc_expr **initp, locus *var_locus) sym->value = init; if (sym->attr.save == SAVE_NONE) - sym->attr.save = SAVE_IMPLICIT; + { + sym->attr.save = SAVE_IMPLICIT; + if (warn_surprising) + gfc_warning (OPT_Wsurprising, "%qs at %L has an implicit SAVE " + "attribute", sym->name, &sym->declared_at); + } *initp = NULL; } @@ -5868,7 +5873,12 @@ match_attr_spec (void) || gfc_current_state () == COMP_SUBMODULE) && !current_attr.save && (gfc_option.allow_std & GFC_STD_F2008) != 0) - current_attr.save = SAVE_IMPLICIT; + { + current_attr.save = SAVE_IMPLICIT; + if (warn_surprising) + gfc_warning (OPT_Wsurprising, "Entity at %C has an implicit SAVE " + "attribute"); + } colon_seen = 1; return MATCH_YES; -- You are receiving this mail because: You are on the CC list for the bug.
It appears that Lfortran issues a message for this case. See: https://github.com/j3-fortran/fortran_proposals/issues/83#issuecomment-1906266587