Bug 84382 - add command-line options -std=gnu2003 and -std=gnu2008 for gfortran
Summary: add command-line options -std=gnu2003 and -std=gnu2008 for gfortran
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 8.0
: P5 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-02-14 15:56 UTC by janus
Modified: 2019-12-24 18:23 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2019-04-04 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description janus 2018-02-14 15:56:47 UTC
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.
Comment 1 Dominique d'Humieres 2019-04-04 16:02:56 UTC
Fortran is not C! WTF?
Comment 2 janus 2019-04-04 21:11:43 UTC
(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?
Comment 3 kargls 2019-04-04 23:40:43 UTC
(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.
Comment 4 janus 2019-04-05 10:24:15 UTC
(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.
Comment 5 Steve Kargl 2019-04-05 23:15:30 UTC
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.
Comment 6 Steve Kargl 2019-04-06 02:20:31 UTC
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}