The following is supposed to be valid Fortran 2008 code, IIUC: program forall_2008 forall (integer(kind=4) :: i = 1:10) end forall end However, gfortran currently throws a "Syntax error in FORALL statement".
My version of the Fortran 2008 standard has: R752 forall-header is ( [ type-spec :: ] forall-triplet-spec-list [, scalar-mask-expr ] ) and C735 (R752) type-spec shall specify type integer. Actually it seems that not only specifying a kind is new, but specifying the type at all (which is restricted to integer anyway). gfortran also rejects this simpler version (which only specifies the type, but no explicit kind): forall (integer :: i = 1:10)
Confirmed.
See array.c(gfc_match_array_constructor) for code to match a type spec in an array constructor. Looks like a copy and paste with an additional check for INTEGER to match.c:match_forall_header mamy fix this bug.
Note: These things (R752 and C735) also apply to DO CONCURRENT (PR 44646).
It appears that the link to this PR shall replace the link to PR4646 at the Fortran2008 wiki status page: https://gcc.gnu.org/wiki/Fortran2008Status The PR44646 (feature request) is closed now.
(In reply to Jürgen Reuter from comment #5) > It appears that the link to this PR shall replace the link to PR4646 at the > Fortran2008 wiki status page: https://gcc.gnu.org/wiki/Fortran2008Status > The PR44646 (feature request) is closed now. Typo: first PR should be also PR44646.
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c index d148de3e3b5..d7668f6a928 100644 --- a/gcc/fortran/match.c +++ b/gcc/fortran/match.c @@ -2350,6 +2350,34 @@ match_forall_iterator (gfc_forall_iterator **result) gfc_forall_iterator *iter; locus where; match m; + gfc_typespec ts; + bool seen_ts; + + /* In Fortran 2018, one can do "forall (integer :: i = 1:20)". + Try to match an optional "type-spec ::" */ + seen_ts = false; + gfc_clear_ts (&ts); + m = gfc_match_type_spec (&ts); + if (m == MATCH_YES) + { + seen_ts = (gfc_match (" ::") == MATCH_YES); + + if (seen_ts) + { + if (!gfc_notify_std (GFC_STD_F2018, "FORALL includes a " + "type specification at %C")) + return MATCH_ERROR; + + if (ts.type != BT_INTEGER) + { + gfc_error ("Type-spec at %L shall be INTEGER", + &gfc_current_locus); + return MATCH_ERROR; + } + } + } + else if (m == MATCH_ERROR) + return m; where = gfc_current_locus; iter = XCNEW (gfc_forall_iterator); @@ -2358,6 +2386,9 @@ match_forall_iterator (gfc_forall_iterator **result) if (m != MATCH_YES) goto cleanup; + if (seen_ts) + iter->var->ts = ts; + if (gfc_match_char ('=') != MATCH_YES || iter->var->expr_type != EXPR_VARIABLE) {
(In reply to kargl from comment #7) > diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c > index d148de3e3b5..d7668f6a928 100644 > --- a/gcc/fortran/match.c > +++ b/gcc/fortran/match.c > @@ -2350,6 +2350,34 @@ match_forall_iterator (gfc_forall_iterator **result) > gfc_forall_iterator *iter; > locus where; > match m; > + gfc_typespec ts; > + bool seen_ts; > + > + /* In Fortran 2018, one can do "forall (integer :: i = 1:20)". s/2018/2008 > + Try to match an optional "type-spec ::" */ > + seen_ts = false; > + gfc_clear_ts (&ts); > + m = gfc_match_type_spec (&ts); > + if (m == MATCH_YES) > + { > + seen_ts = (gfc_match (" ::") == MATCH_YES); > + > + if (seen_ts) > + { > + if (!gfc_notify_std (GFC_STD_F2018, "FORALL includes a " s/2018/2008 > + "type specification at %C")) > + return MATCH_ERROR; > + > + if (ts.type != BT_INTEGER) > + { > + gfc_error ("Type-spec at %L shall be INTEGER", > + &gfc_current_locus); > + return MATCH_ERROR; > + } > + } > + } > + else if (m == MATCH_ERROR) > + return m; > > where = gfc_current_locus; > iter = XCNEW (gfc_forall_iterator); > @@ -2358,6 +2386,9 @@ match_forall_iterator (gfc_forall_iterator **result) > if (m != MATCH_YES) > goto cleanup; > > + if (seen_ts) > + iter->var->ts = ts; > + > if (gfc_match_char ('=') != MATCH_YES > || iter->var->expr_type != EXPR_VARIABLE) > {
(In reply to kargl from comment #7) > diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c The patch unfortunately seems incomplete. It fails when using IMPLICIT NONE or -fimplicit-none with: pr78219.f90:3:30: 3 | forall (integer(kind=4) :: i = 1:10) | 1 Error: Symbol 'i' at (1) has no IMPLICIT type and similarly for pr102371.
*** Bug 102371 has been marked as a duplicate of this bug. ***
(In reply to anlauf from comment #9) > (In reply to kargl from comment #7) > > diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c > > The patch unfortunately seems incomplete. It fails when using IMPLICIT NONE > or -fimplicit-none with: > > pr78219.f90:3:30: > > 3 | forall (integer(kind=4) :: i = 1:10) > | 1 > Error: Symbol 'i' at (1) has no IMPLICIT type > > and similarly for pr102371. https://gcc.gnu.org/pipermail/gcc-bugs/2021-September/757723.html
Has this been fixed in a more recent version of gfortran?