This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Patch, Fortran] Renaming operators on the USE statement
- From: Tobias Burnus <burnus at net-b dot de>
- To: "'fortran at gcc dot gnu dot org'" <fortran at gcc dot gnu dot org>, gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 05 Mar 2007 12:56:29 +0100
- Subject: [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" } }