This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PR fortran/82865] Fix PDT declarations being parsed as PRINT statements with -fdec


One extension enabled by -fdec is the ability to interpret TYPE ....
as a PRINT statement for compatibility purposes. When PDTs were
introduced, the code that handles -fde TYPE matching was not updated.
This patch fixes TYPE matching to no longer interpret <TYPE
name(parameter)> as a PRINT statement when -fdec is asserted. Passes
regression tests as well.

The patch is attached. OK for trunk and 7/8-branch?

0dd08cefc2476014487b3eeab059784ab21bb41b Mon Sep 17 00:00:00 2001
From: Fritz Reese <fritzoreese@gmail.com>
Date: Wed, 27 Jun 2018 15:43:45 -0400
Subject: [PATCH 3/3] PR fortran/82865

Do not override PDT declarations from gfc_match_type with -fdec.

gcc/fortran/

        * decl.c (gfc_match_type): Refactor and check for PDT declarations.

gcc/testsuite/

        * gfortran.dg/dec_type_print_2.f03: New testcase.
---
 gcc/fortran/decl.c                             | 66 +++++++++++++-------------
 gcc/testsuite/gfortran.dg/dec_type_print_2.f03 | 59 +++++++++++++++++++++++
 2 files changed, 93 insertions(+), 32 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/dec_type_print_2.f03
From 0dd08cefc2476014487b3eeab059784ab21bb41b Mon Sep 17 00:00:00 2001
From: Fritz Reese <fritzoreese@gmail.com>
Date: Wed, 27 Jun 2018 15:43:45 -0400
Subject: [PATCH 3/3] PR fortran/82865

Do not override PDT declarations from gfc_match_type with -fdec.

gcc/fortran/

	* decl.c (gfc_match_type): Refactor and check for PDT declarations.

gcc/testsuite/

	* gfortran.dg/dec_type_print_2.f03: New testcase.
---
 gcc/fortran/decl.c                             | 66 +++++++++++++-------------
 gcc/testsuite/gfortran.dg/dec_type_print_2.f03 | 59 +++++++++++++++++++++++
 2 files changed, 93 insertions(+), 32 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/dec_type_print_2.f03

diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index af724658d8d..ef59d1679ed 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -9607,9 +9607,9 @@ gfc_match_structure_decl (void)
 
 
 /* This function does some work to determine which matcher should be used to
- * match a statement beginning with "TYPE". This is used to disambiguate TYPE
+ * match a statement beginning with "TYPE".  This is used to disambiguate TYPE
  * as an alias for PRINT from derived type declarations, TYPE IS statements,
- * and derived type data declarations.  */
+ * and [parameterized] derived type declarations.  */
 
 match
 gfc_match_type (gfc_statement *st)
@@ -9636,11 +9636,7 @@ gfc_match_type (gfc_statement *st)
   /* If we see an attribute list before anything else it's definitely a derived
    * type declaration.  */
   if (gfc_match (" ,") == MATCH_YES || gfc_match (" ::") == MATCH_YES)
-    {
-      gfc_current_locus = old_loc;
-      *st = ST_DERIVED_DECL;
-      return gfc_match_derived_decl ();
-    }
+    goto derived;
 
   /* By now "TYPE" has already been matched. If we do not see a name, this may
    * be something like "TYPE *" or "TYPE <fmt>".  */
@@ -9655,29 +9651,11 @@ gfc_match_type (gfc_statement *st)
 	  *st = ST_WRITE;
 	  return MATCH_YES;
 	}
-      gfc_current_locus = old_loc;
-      *st = ST_DERIVED_DECL;
-      return gfc_match_derived_decl ();
+      goto derived;
     }
 
-  /* A derived type declaration requires an EOS. Without it, assume print.  */
-  m = gfc_match_eos ();
-  if (m == MATCH_NO)
-    {
-      /* Check manually for TYPE IS (... - this is invalid print syntax.  */
-      if (strncmp ("is", name, 3) == 0
-	  && gfc_match (" (", name) == MATCH_YES)
-	{
-	  gfc_current_locus = old_loc;
-	  gcc_assert (gfc_match (" is") == MATCH_YES);
-	  *st = ST_TYPE_IS;
-	  return gfc_match_type_is ();
-	}
-      gfc_current_locus = old_loc;
-      *st = ST_WRITE;
-      return gfc_match_print ();
-    }
-  else
+  /* Check for EOS.  */
+  if (gfc_match_eos () == MATCH_YES)
     {
       /* By now we have "TYPE <name> <EOS>". Check first if the name is an
        * intrinsic typename - if so let gfc_match_derived_decl dump an error.
@@ -9690,12 +9668,36 @@ gfc_match_type (gfc_statement *st)
 	  *st = ST_DERIVED_DECL;
 	  return m;
 	}
-      gfc_current_locus = old_loc;
-      *st = ST_WRITE;
-      return gfc_match_print ();
     }
+  else
+    {
+      /* Here we have "TYPE <name>". Check for <TYPE IS (> or a PDT declaration
+	 like <type name(parameter)>.  */
+      gfc_gobble_whitespace ();
+      bool paren = gfc_peek_ascii_char () == '(';
+      if (paren)
+	{
+	  if (strcmp ("is", name) == 0)
+	    goto typeis;
+	  else
+	    goto derived;
+	}
+    }
+
+  /* Treat TYPE... like PRINT...  */
+  gfc_current_locus = old_loc;
+  *st = ST_WRITE;
+  return gfc_match_print ();
 
-  return MATCH_NO;
+derived:
+  gfc_current_locus = old_loc;
+  *st = ST_DERIVED_DECL;
+  return gfc_match_derived_decl ();
+
+typeis:
+  gfc_current_locus = old_loc;
+  *st = ST_TYPE_IS;
+  return gfc_match_type_is ();
 }
 
 
diff --git a/gcc/testsuite/gfortran.dg/dec_type_print_2.f03 b/gcc/testsuite/gfortran.dg/dec_type_print_2.f03
new file mode 100644
index 00000000000..31b8c3ad934
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_type_print_2.f03
@@ -0,0 +1,59 @@
+! { dg-do run }
+! { dg-options "-fdec -fcheck=all" }
+!
+! Verify that -fdec does not break parsing of PDTs.
+! This test code is copied from pdt_1.f03 but compiled with -fdec.
+!
+program main
+  implicit none
+  integer, parameter :: ftype = kind(0.0e0)
+  integer :: pdt_len = 4
+  integer :: i
+  type :: mytype (a,b)
+    integer, kind :: a = kind(0.0d0)
+    integer, LEN :: b
+    integer :: i
+    real(kind = a) :: d(b, b)
+    character (len = b*b) :: chr
+  end type
+
+  type(mytype(b=4)) :: z(2)
+  type(mytype(ftype, 4)) :: z2
+
+  z(1)%i = 1
+  z(2)%i = 2
+  z(1)%d = reshape ([(real(i), i = 1, 16)],[4,4])
+  z(2)%d = 10*z(1)%d
+  z(1)%chr = "hello pdt"
+  z(2)%chr = "goodbye pdt"
+
+  z2%d = z(1)%d * 10 - 1
+  z2%chr = "scalar pdt"
+
+  call foo (z)
+  call bar (z)
+  call foobar (z2)
+contains
+  elemental subroutine foo (arg)
+    type(mytype(8,*)), intent(in) :: arg
+    if (arg%i .eq. 1) then
+      if (trim (arg%chr) .ne. "hello pdt") error stop
+      if (int (sum (arg%d)) .ne. 136) error stop
+    else if (arg%i .eq. 2 ) then
+      if (trim (arg%chr) .ne. "goodbye pdt") error stop
+      if (int (sum (arg%d)) .ne. 1360) error stop
+    else
+      error stop
+    end if
+  end subroutine
+  subroutine bar (arg)
+    type(mytype(b=4)) :: arg(:)
+    if (int (sum (arg(1)%d)) .ne. 136) call abort
+    if (trim (arg(2)%chr) .ne. "goodbye pdt") call abort
+  end subroutine
+  subroutine foobar (arg)
+    type(mytype(ftype, pdt_len)) :: arg
+    if (int (sum (arg%d)) .ne. 1344) call abort
+    if (trim (arg%chr) .ne. "scalar pdt") call abort
+  end subroutine
+end
-- 
2.12.2


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]