I've committed the attached patch after successful regression tests on x86_64-*-freebsd. The patch returns MATCH_NO when matching is done for a COMMON statement, but the statement in fact is not COMMON. See testcases.
While here I corrected the recording of the wrong revision number in the ChangeLogs from my previous commit. 2019-06-27 Steven G. Kargl <ka...@gcc.gnu.org> PR fortran/90987 * match.c (gfc_match_common): Adjust parsing of fixed and free form source code containing, e.g., COMMONI. 2019-06-27 Steven G. Kargl <ka...@gcc.gnu.org> PR fortran/90987 * gfortran.dg/common_1.f: new test. * gfortran.dg/common_26.f90: Ditto. -- Steve
Index: gcc/fortran/match.c =================================================================== --- gcc/fortran/match.c (revision 272755) +++ gcc/fortran/match.c (working copy) @@ -5115,7 +5115,15 @@ gfc_match_common (void) gfc_array_spec *as; gfc_equiv *e1, *e2; match m; + char c; + /* COMMON has been matched. In free form source code, the next character + needs to be whitespace or '/'. Check that here. Fixed form source + code needs to be checked below. */ + c = gfc_peek_ascii_char (); + if (gfc_current_form == FORM_FREE && !gfc_is_whitespace (c) && c != '/') + return MATCH_NO; + as = NULL; for (;;) @@ -5279,10 +5287,24 @@ gfc_match_common (void) gfc_gobble_whitespace (); if (gfc_match_eos () == MATCH_YES) goto done; - if (gfc_peek_ascii_char () == '/') + c = gfc_peek_ascii_char (); + if (c == '/') break; - if (gfc_match_char (',') != MATCH_YES) - goto syntax; + if (c != ',') + { + /* In Fixed form source code, gfortran can end up here for an + expression of the form COMMONI = RHS. This may not be an + error, so return MATCH_NO. */ + if (gfc_current_form == FORM_FIXED && c == '=') + { + gfc_free_array_spec (as); + return MATCH_NO; + } + goto syntax; + } + else + gfc_match_char (','); + gfc_gobble_whitespace (); if (gfc_peek_ascii_char () == '/') break; @@ -6248,6 +6270,7 @@ gfc_match_select_type (void) sym->attr.flavor = FL_VARIABLE; sym->attr.referenced = 1; sym->attr.class_ok = 1; + sym->attr.target = expr2->symtree->n.sym->attr.target; } else { Index: gcc/testsuite/gfortran.dg/common_1.f =================================================================== --- gcc/testsuite/gfortran.dg/common_1.f (nonexistent) +++ gcc/testsuite/gfortran.dg/common_1.f (working copy) @@ -0,0 +1,14 @@ +! { dg-do compile } + module mymod + type :: mytyp + integer :: i + end type mytyp + contains + subroutine mysub + implicit none + type(mytyp) :: a + integer :: commoni,commonj + commoni = a%i + commonj = a%j ! { dg-error "is not a member of" } + end subroutine mysub + end module mymod Index: gcc/testsuite/gfortran.dg/common_26.f90 =================================================================== --- gcc/testsuite/gfortran.dg/common_26.f90 (nonexistent) +++ gcc/testsuite/gfortran.dg/common_26.f90 (working copy) @@ -0,0 +1,14 @@ +! { dg-do compile } +module mymod + type :: mytyp + integer :: i + end type mytyp +contains + subroutine mysub + implicit none + type(mytyp) :: a + integer :: commoni,commonj + commoni = a%i + commonj = a%j ! { dg-error "is not a member of" } + end subroutine mysub +end module mymod