diff mbox series

[Committed] PF fortran/90987 -- Adjust parsing of COMMONI

Message ID 20190627175548.GA47877@troutmask.apl.washington.edu
State New
Headers show
Series [Committed] PF fortran/90987 -- Adjust parsing of COMMONI | expand

Commit Message

Steve Kargl June 27, 2019, 5:55 p.m. UTC
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  <kargl@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  <kargl@gcc.gnu.org>

	PR fortran/90987
	* gfortran.dg/common_1.f: new test.
	* gfortran.dg/common_26.f90: Ditto.
diff mbox series

Patch

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