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]

[Patch, Fortran] Renaming operators on the USE statement


:ADDPATCH fortran:

"3.6 Renaming operators on the USE statement
In Fortran 2003, it is permissible to rename operators that are not
intrinsic operators:
USE MY_MODULE, OPERATOR(.MyAdd.) => OPERATOR(.ADD.)
This allows .MyAdd. to denote the operator .ADD. accessed from the module."

Bootstrapped and regression tested on x86_64-unknown-linux-gnu. Ok for
the trunk?

Tobias
2007-03-05  Tobias Burnus  <burnus@net-b.de>

	* module.c (gfc_match_use): Support renaming of operators
	in USE statements.

2007-03-05  Tobias Burnus  <burnus@net-b.de>

	* gfortran.dg/use_5.f90: New test.
	* gfortran.dg/use_6.f90: Ditto.
	* gfortran.dg/use_7.f90: Ditto.

Index: gcc/fortran/module.c
===================================================================
--- gcc/fortran/module.c	(Revision 122530)
+++ gcc/fortran/module.c	(Arbeitskopie)
@@ -488,7 +488,7 @@
 {
   char name[GFC_MAX_SYMBOL_LEN + 1], module_nature[GFC_MAX_SYMBOL_LEN + 1];
   gfc_use_rename *tail = NULL, *new;
-  interface_type type;
+  interface_type type, type2;
   gfc_intrinsic_op operator;
   match m;
 
@@ -588,9 +588,16 @@
 	  gfc_error ("Missing generic specification in USE statement at %C");
 	  goto cleanup;
 
+	case INTERFACE_USER_OP:
 	case INTERFACE_GENERIC:
 	  m = gfc_match (" =>");
 
+	  if (type == INTERFACE_USER_OP && m == MATCH_YES
+	      && (gfc_notify_std (GFC_STD_F2003, "Fortran 2003: Renaming "
+				  "operators in USE statements at %C")
+	         == FAILURE))
+	    goto cleanup;
+
 	  if (only_flag)
 	    {
 	      if (m != MATCH_YES)
@@ -598,8 +605,9 @@
 	      else
 		{
 		  strcpy (new->local_name, name);
-
-		  m = gfc_match_name (new->use_name);
+		  m = gfc_match_generic_spec (&type2, new->use_name, &operator);
+		  if (type != type2)
+		    goto syntax;
 		  if (m == MATCH_NO)
 		    goto syntax;
 		  if (m == MATCH_ERROR)
@@ -612,19 +620,20 @@
 		goto syntax;
 	      strcpy (new->local_name, name);
 
-	      m = gfc_match_name (new->use_name);
+	      m = gfc_match_generic_spec (&type2, new->use_name, &operator);
+	      if (type != type2)
+		goto syntax;
 	      if (m == MATCH_NO)
 		goto syntax;
 	      if (m == MATCH_ERROR)
 		goto cleanup;
 	    }
 
+	  if (type == INTERFACE_USER_OP)
+	    new->operator = operator;
+
 	  break;
 
-	case INTERFACE_USER_OP:
-	  strcpy (new->use_name, name);
-	  /* Fall through */
-
 	case INTERFACE_INTRINSIC_OP:
 	  new->operator = operator;
 	  break;
Index: gcc/testsuite/gfortran.dg/use_4.f90
===================================================================
--- gcc/testsuite/gfortran.dg/use_4.f90	(Revision 0)
+++ gcc/testsuite/gfortran.dg/use_4.f90	(Revision 0)
@@ -0,0 +1,33 @@
+! { dg-do "compile" }
+! PR fortran/30973
+! Using symbols with the name of the module
+
+module foo
+  integer :: i
+end module foo
+
+module bar
+  integer :: j
+end module bar
+
+module test
+  use foo, only:
+  integer :: foo ! { dg-error "cannot have a type" }
+end module test
+
+module test2
+  use bar, only: foo => j
+  use foo ! ok, unless foo is accessed
+end module test2
+
+module test3
+  use bar, only: foo => j
+  use foo ! ok, unless foo is accessed
+  foo = 5 ! { dg-error "is an ambiguous reference to 'j'" }
+end module test3
+
+program test_foo
+  use foo, only: foo  ! { dg-error "been used as an external module name" }
+  use foo, only: i => foo! { dg-error "been used as an external module name" }
+  use foo, only: foo => i! { dg-error "been used as an external module name" }
+end program
Index: gcc/testsuite/gfortran.dg/use_5.f90
===================================================================
--- gcc/testsuite/gfortran.dg/use_5.f90	(Revision 0)
+++ gcc/testsuite/gfortran.dg/use_5.f90	(Revision 0)
@@ -0,0 +1,49 @@
+! { dg-do "run" }
+! Renaming of operators
+module z
+  interface operator(.addfive.)
+    module procedure sub2
+  end interface
+contains
+function sub2(x)
+  integer :: sub
+  integer,intent(in) :: x
+  sub2 = x + 5
+end function sub2
+end module z
+
+module y
+  interface operator(.addfive.)
+    module procedure sub
+  end interface
+contains
+function sub(x)
+  integer :: sub
+  integer,intent(in) :: x
+  sub = x + 15
+end function sub
+end module y
+
+module x
+  interface operator(.addfive.)
+    module procedure sub
+  end interface
+contains
+function sub(x)
+  integer :: sub
+  integer,intent(in) :: x
+  sub = x + 25
+end function sub
+end module x
+
+use x, only : operator(.bar.) => operator(.addfive.)
+use y, operator(.my.) => operator(.addfive.)
+use z
+ integer :: i
+ i = 2
+ if ((.bar. i) /= 2+25) call abort ()
+ if ((.my. i) /= 2+15) call abort ()
+ if ((.addfive. i) /= 2+5) call abort ()
+end
+
+! { dg-final { cleanup-tree-dump "x y z" } }
Index: gcc/testsuite/gfortran.dg/use_6.f90
===================================================================
--- gcc/testsuite/gfortran.dg/use_6.f90	(Revision 0)
+++ gcc/testsuite/gfortran.dg/use_6.f90	(Revision 0)
@@ -0,0 +1,45 @@
+! { dg-do "compile" }
+! { dg-options "-std=f95" }
+! Renaming of operators
+module z
+  interface operator(.addfive.)
+    module procedure sub2
+  end interface
+contains
+function sub2(x)
+  integer :: sub
+  integer,intent(in) :: x
+  sub2 = x + 5
+end function sub2
+end module z
+
+module y
+  interface operator(.addfive.)
+    module procedure sub
+  end interface
+contains
+function sub(x)
+  integer :: sub
+  integer,intent(in) :: x
+  sub = x + 15
+end function sub
+end module y
+
+module x
+  interface operator(.addfive.)
+    module procedure sub
+  end interface
+contains
+function sub(x)
+  integer :: sub
+  integer,intent(in) :: x
+  sub = x + 25
+end function sub
+end module x
+
+use x, only : operator(.bar.) => operator(.addfive.) ! { dg-error "Fortran 2003: Renaming operators in USE statements" }
+use y, operator(.my.) => operator(.addfive.) ! { dg-error "Fortran 2003: Renaming operators in USE statements" }
+use z
+end
+
+! { dg-final { cleanup-tree-dump "x y z" } }
Index: gcc/testsuite/gfortran.dg/use_7.f90
===================================================================
--- gcc/testsuite/gfortran.dg/use_7.f90	(Revision 0)
+++ gcc/testsuite/gfortran.dg/use_7.f90	(Revision 0)
@@ -0,0 +1,49 @@
+! { dg-do "compile" }
+! Renaming of operators
+module z
+  type myT
+    integer :: t
+  end type myT
+  interface operator(+)
+    module procedure sub2
+  end interface
+contains
+function sub2(x)
+  type(myT) :: sub2
+  type(myT),intent(in) :: x
+  sub2%t = x%t + 5
+end function sub2
+end module z
+
+module y
+  interface operator(.addfive.)
+    module procedure sub
+  end interface
+contains
+function sub(x)
+  integer :: sub
+  integer,intent(in) :: x
+  sub = x + 15
+end function sub
+end module y
+
+module x
+  interface operator(.addfive.)
+    module procedure sub
+  end interface
+contains
+function sub(x)
+  integer :: sub
+  integer,intent(in) :: x
+  sub = x + 25
+end function sub
+end module x
+
+use z, operator(-) => operator(+) ! { dg-error "Syntax error in USE statement" }
+use z, operator(.op.) => operator(+) ! { dg-error "Syntax error in USE statement" }
+use x, only : bar => operator(.addfive.) ! { dg-error "Syntax error in USE statement" }
+use y, operator(.my.) => sub ! { dg-error "Syntax error in USE statement" }
+use y, operator(+) => operator(.addfive.) ! { dg-error "Syntax error in USE statement" }
+end
+
+! { dg-final { cleanup-tree-dump "x y z" } }


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