In analogy to the g++ options -std=gnu++17 etc (as apposed to -std=c++17), gfortran should have options like -std=gnu2003 and -std=gnu2008 that instruct the compiler to adhere to a given Fortran standard plus GNU extensions.
Fortran is not C! WTF?
(In reply to Dominique d'Humieres from comment #1) > Fortran is not C! True. Fortran is not C is not C++. The main difference wrt this PR is possibly that the latter two have a large enough user base, so that a significant amount of people actually use the options mentioned above. > WTF? Giving that questions back to you, Dominique: WTF? Which problem do you think you solve by closing PRs that have not been fixed?
(In reply to janus from comment #2) > (In reply to Dominique d'Humieres from comment #1) > > Fortran is not C! > > True. Fortran is not C is not C++. The main difference wrt this PR is > possibly that the latter two have a large enough user base, so that a > significant amount of people actually use the options mentioned above. > How do you propose to enforce a certain standard and allow GNU extensions? For example, -std=gnu2003 would enforce Fortran 2003, but allow GNU extensions. The problem is that gfortran allows several extensions that violate the standard. A simple example is program foo integer :: i = z'1234' print *, i end program foo % gfcx -o z a.f90 && ./z 4660 % gfcx -o z -std=f2003 a.f90 && ./z a.f90:2:18: 2 | integer :: i = z'1234' | 1 Error: GNU Extension: BOZ literal at (1) outside a DATA statement and outside INT/REAL/DBLE/CMPLX gfortran even allows extensions that aren't caught by the -std options and are not document! program foo integer :: i = 42 print '(i0)', i + z'1234' end program foo %gfcx -o z a.f90 && ./z 4702 % gfcx -o z -std=f2003 a.f90 && ./z 4702 I think it will becomes a endless discussion on what should and should not be covered under -std=gnu2003. What we have now seems to be the most reasonable approach (with the available man power to address problem). Either a user wants GNU Fortran (ie., -std=gnu, the default behavior) or a user wants a stricter adherence to a particular standard. (For the record, I plan to remove both of the above extensions in 10.0). > > WTF? > > Giving that questions back to you, Dominique: WTF? Which problem do you > think you solve by closing PRs that have not been fixed? Yeah, I saw Dominique's comment #1, and thought that it might be a tad bit over-the-top given the quality and quantity of your contributions to gfortran.
(In reply to kargl from comment #3) > How do you propose to enforce a certain standard and allow > GNU extensions? For example, -std=gnu2003 would enforce > Fortran 2003, but allow GNU extensions. The problem is that > gfortran allows several extensions that violate the > standard. The idea is that -std=gnu2003 would allow 2003 features plus GNU extensions, but reject any 2008 and 2018 features (like submodules and coarrays). > gfortran even allows extensions that aren't caught by the -std > options and are not document! That's a separate issue and discussion, not related to this PR. Ideally all extensions should be caught and documented, of course. > I think it will becomes a endless discussion on what should > and should not be covered under -std=gnu2003. I don't see that. We already have a more-or-less complete classification of what is a 2003 or 2008 feature and what is a non-std extension. My proposal would simply introduce new options corresponding to different combinations of feature classes. > What we have > now seems to be the most reasonable approach (with the > available man power to address problem). Either a user > wants GNU Fortran (ie., -std=gnu, the default behavior) or > a user wants a stricter adherence to a particular standard. I have not really thought about how to implement this PR. I assumed it would be easy to modify/extend gfc_notify_std & friends to accomomdate some new feature levels. At some point I just had the idea for this PR and I wanted to write it down for the future to think about and evaluate the idea. I haven't started an implementation because it's not high priority for me. If it's simply not needed or there is consensus that it's not worth the effort, then I'm willing to discuss and possibly close this PR, but certainly not due to someone yelling WTF. Also I don't see what's wrong about letting it hang in bugzilla until it becomes a priority/necessity for someone.
On Fri, Apr 05, 2019 at 10:24:15AM +0000, janus at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84382 > > --- Comment #4 from janus at gcc dot gnu.org --- > (In reply to kargl from comment #3) > > How do you propose to enforce a certain standard and allow > > GNU extensions? For example, -std=gnu2003 would enforce > > Fortran 2003, but allow GNU extensions. The problem is that > > gfortran allows several extensions that violate the > > standard. > > The idea is that -std=gnu2003 would allow 2003 features plus GNU extensions, > but reject any 2008 and 2018 features (like submodules and coarrays). > I see. It seems counter-intuitive to me for someone to want, for example, -std=gnu2003, which accepts the garbage that GFC_STD_GNU permits, F2003 conformance, and suppresses F2008 and F2018. I would rather have gfortran encourage programmers to write standard conforming code. In any event, looking at fortran/libgfortran.h, we have #define GFC_STD_OPT_F95 (GFC_STD_F77 | GFC_STD_F95 | GFC_STD_F95_OBS \ | GFC_STD_F2008_OBS | GFC_STD_F2018_OBS \ | GFC_STD_F2018_DEL) #define GFC_STD_OPT_F03 (GFC_STD_OPT_F95 | GFC_STD_F2003) #define GFC_STD_OPT_F08 (GFC_STD_OPT_F03 | GFC_STD_F2008) #define GFC_STD_OPT_F18 ((GFC_STD_OPT_F08 | GFC_STD_F2018) \ & (~GFC_STD_F2018_DEL)) We could add #define GFC_STD_OPT_GNU03 (GFC_STD_OPT_F03 | GFC_STD_GNU) #define GFC_STD_OPT_GNU08 (GFC_STD_OPT_F08 | GFC_STD_GNU) #define GFC_STD_OPT_GNU18 (GFC_STD_OPT_F18 | GFC_STD_GNU) then in options.c (gfc_handle_options) the case statements would be case OPT_std_gnu2003: gfc_option.allow_std = GFC_STD_OPT_GNU03; gfc_option.warn_std = GFC_STD_F95_OBS; gfc_option.max_identifier_length = 63; warn_ampersand = 1; warn_tabs = 1; break; case OPT_std_gnu2008: gfc_option.allow_std = GFC_STD_OPT_GNU08; gfc_option.warn_std = GFC_STD_F95_OBS | GFC_STD_F2008_OBS; gfc_option.max_identifier_length = 63; warn_ampersand = 1; warn_tabs = 1; break; case OPT_std_gnu2018: gfc_option.allow_std = GFC_STD_OPT_F18; gfc_option.warn_std=GFC_STD_F95_OBS|GFC_STD_F2008_OBS|GFC_STD_F2018_OBS; gfc_option.max_identifier_length = 63; warn_ampersand = 1; warn_tabs = 1; break; then finally lang.opt (and of course documentation would add) std=gnu2003 Fortran Conform to the ISO Fortran 2003 standard with GNU Fortran extensions. std=gnu2008 Fortran Conform to the ISO Fortran 2008 standard with GNU Fortran extensions. std=gnu2018 Fortran Conform to the ISO Fortran 2018 standard with GNU Fortran extensions.
On Fri, Apr 05, 2019 at 11:15:30PM +0000, sgk at troutmask dot apl.washington.edu wrote: > > We could add > > #define GFC_STD_OPT_GNU03 (GFC_STD_OPT_F03 | GFC_STD_GNU) > #define GFC_STD_OPT_GNU08 (GFC_STD_OPT_F08 | GFC_STD_GNU) > #define GFC_STD_OPT_GNU18 (GFC_STD_OPT_F18 | GFC_STD_GNU) > Against my better judgment. %cat a.f90 program foo integer :: i = z'1234' ! Nonstandard initialization print *, i end program foo % gfcx -o z a.f90 && ./z 4660 % gfcx -o z -std=f2003 a.f90 && ./z a.f90:2:17: 2 | integer :: i = z'1234' ! Nonstandard initialization | 1 Error: GNU Extension: BOZ literal at (1) outside a DATA statement and outside INT/REAL/DBLE/CMPLX % gfcx -o z -std=gnu2003 a.f90 && ./z 4660 Index: gcc/fortran/libgfortran.h =================================================================== --- gcc/fortran/libgfortran.h (revision 270181) +++ gcc/fortran/libgfortran.h (working copy) @@ -46,6 +46,10 @@ along with GCC; see the file COPYING3. If not see #define GFC_STD_OPT_F18 ((GFC_STD_OPT_F08 | GFC_STD_F2018) \ & (~GFC_STD_F2018_DEL)) +#define GFC_STD_OPT_GNU03 (GFC_STD_OPT_F03 | GFC_STD_GNU) +#define GFC_STD_OPT_GNU08 (GFC_STD_OPT_F08 | GFC_STD_GNU) +#define GFC_STD_OPT_GNU18 (GFC_STD_OPT_F18 | GFC_STD_GNU) + /* Bitmasks for the various FPE that can be enabled. These need to be straight integers e.g., 8 instead of (1<<3), because they will be included in Fortran source. */ #define GFC_FPE_INVALID 1 Index: gcc/fortran/lang.opt =================================================================== --- gcc/fortran/lang.opt (revision 270181) +++ gcc/fortran/lang.opt (working copy) @@ -826,6 +826,18 @@ std=gnu Fortran Conform to nothing in particular. +std=gnu2003 +Fortran +Conform to the ISO Fortran 2003 standard with GNU Fortran extensions. + +std=gnu2008 +Fortran +Conform to the ISO Fortran 2008 standard with GNU Fortran extensions. + +std=gnu2018 +Fortran +Conform to the ISO Fortran 2018 standard with GNU Fortran extensions. + std=legacy Fortran Accept extensions to support legacy code. Index: gcc/fortran/options.c =================================================================== --- gcc/fortran/options.c (revision 270181) +++ gcc/fortran/options.c (working copy) @@ -778,6 +778,31 @@ gfc_handle_option (size_t scode, const char *arg, HOST set_default_std_flags (); break; + case OPT_std_gnu2003: + gfc_option.allow_std = GFC_STD_OPT_GNU03; + gfc_option.warn_std = GFC_STD_F95_OBS; + gfc_option.max_identifier_length = 63; + warn_ampersand = 1; + warn_tabs = 1; + break; + + case OPT_std_gnu2008: + gfc_option.allow_std = GFC_STD_OPT_GNU08; + gfc_option.warn_std = GFC_STD_F95_OBS | GFC_STD_F2008_OBS; + gfc_option.max_identifier_length = 63; + warn_ampersand = 1; + warn_tabs = 1; + break; + + case OPT_std_gnu2018: + gfc_option.allow_std = GFC_STD_OPT_GNU18; + gfc_option.warn_std = GFC_STD_F95_OBS | GFC_STD_F2008_OBS + | GFC_STD_F2018_OBS; + gfc_option.max_identifier_length = 63; + warn_ampersand = 1; + warn_tabs = 1; + break; + case OPT_std_legacy: set_default_std_flags (); gfc_option.warn_std = 0; Index: gcc/fortran/invoke.texi =================================================================== --- gcc/fortran/invoke.texi (revision 270181) +++ gcc/fortran/invoke.texi (working copy) @@ -492,23 +492,28 @@ representation of the translated Fortran code, produce @item -std=@var{std} @opindex @code{std=}@var{std} option -Specify the standard to which the program is expected to conform, -which may be one of @samp{f95}, @samp{f2003}, @samp{f2008}, -@samp{f2018}, @samp{gnu}, or @samp{legacy}. The default value for -@var{std} is @samp{gnu}, which specifies a superset of the latest -Fortran standard that includes all of the extensions supported by GNU -Fortran, although warnings will be given for obsolete extensions not +Specify the standard to which the program is expected to conform +which may be one of @samp{f95}, @samp{f2003}, @samp{f2008}, @samp{f2018}, +@samp{gnu}, @samp{gnu2003}, @samp{gnu2008}, @samp{gnu2018},or @samp{legacy}. +The default value for @var{std} is @samp{gnu}, which specifies a superset +of the latest Fortran standard that includes all of the extensions supported +by GNU Fortran, although warnings will be given for obsolete extensions not recommended for use in new code. The @samp{legacy} value is equivalent but without the warnings for obsolete extensions, and may -be useful for old non-standard programs. The @samp{f95}, +be useful for old nonstandard programs. The @samp{f95}, @samp{f2003}, @samp{f2008}, and @samp{f2018} values specify strict conformance to the Fortran 95, Fortran 2003, Fortran 2008 and Fortran 2018 standards, respectively; errors are given for all extensions beyond the relevant language standard, and warnings are given for the Fortran 77 features that are permitted but obsolescent in later -standards. The deprecated option @samp{-std=f2008ts} acts as an alias for +standards. The deprecated option @samp{-std=f2008ts} acts as an alias for @samp{-std=f2018}. It is only present for backwards compatibility with earlier gfortran versions and should not be used any more. +The @samp{gnu2003}, @samp{gnu2008}, and @samp{gnu2018} values specify +adherences to the Fortran 2003, Fortran 2008 and Fortran +2018 standards; while allowing GNU Fortran extensions. For example, +@code{std=gnu2003} would reject Fortran 2008 and 2018 feature, but +would allow nonstandard construction such as @code{REAL*4}. @item -ftest-forall-temp @opindex @code{ftest-forall-temp}