diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index c01c4b351b0d0d1b8247055f8b1489c552f83b78..d134e2cadcfe3a9391a96cc1b9e9a15794f1e5a4 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,11 @@ +2009-09-10 Steven G. Kargl <kargl@gcc.gnu.org> + + PR fortran/31292 + * fortran/decl.c(gfc_match_modproc): Check that module procedures + from a module can USEd in module procedure statements in other + program units. Update locus for better error message display. + Detect intrinsic procedures in module procedure statements. + 2009-09-09 Richard Guenther <rguenther@suse.de> PR fortran/41297 diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c index 52796a655750510f6f02dbe9360cabcdb7cb4e6c..3ce7fd4a33753ccff0217138b68a7d565bbcc361 100644 --- a/gcc/fortran/decl.c +++ b/gcc/fortran/decl.c @@ -6485,7 +6485,10 @@ gfc_match_modproc (void) module_ns = gfc_current_ns->parent; for (; module_ns; module_ns = module_ns->parent) - if (module_ns->proc_name->attr.flavor == FL_MODULE) + if (module_ns->proc_name->attr.flavor == FL_MODULE + || module_ns->proc_name->attr.flavor == FL_PROGRAM + || (module_ns->proc_name->attr.flavor == FL_PROCEDURE + && !module_ns->proc_name->attr.contained)) break; if (module_ns == NULL) @@ -6497,6 +6500,7 @@ gfc_match_modproc (void) for (;;) { + locus old_locus = gfc_current_locus; bool last = false; m = gfc_match_name (name); @@ -6517,6 +6521,13 @@ gfc_match_modproc (void) if (gfc_get_symbol (name, module_ns, &sym)) return MATCH_ERROR; + if (sym->attr.intrinsic) + { + gfc_error ("Intrinsic procedure at %L cannot be a MODULE " + "PROCEDURE", &old_locus); + return MATCH_ERROR; + } + if (sym->attr.proc != PROC_MODULE && gfc_add_procedure (&sym->attr, PROC_MODULE, sym->name, NULL) == FAILURE) @@ -6526,6 +6537,7 @@ gfc_match_modproc (void) return MATCH_ERROR; sym->attr.mod_proc = 1; + sym->declared_at = old_locus; if (last) break; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3a6e97a8ea4e204f4b0d24a152c01e06fc781fae..7b23648297d5d59b4da18ea41ec711e0759df4a7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2009-09-10 Steven G. Kargl <kargl@gcc.gnu.org> + + PR fortran/31292 + * gfortran.dg/module_procedure_1.f90: New test. + * gfortran.dg/module_procedure_2.f90: Ditto. + * gfortran.dg/generic_14.f90: Move dg-error to new location. + 2009-09-10 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> James A. Morrison <phython@gcc.gnu.org> diff --git a/gcc/testsuite/gfortran.dg/generic_14.f90 b/gcc/testsuite/gfortran.dg/generic_14.f90 index 3198da1dafc1c66a6ad517ba05bfe1a8d9d75779..e95f6f2edebcfbb6c11a1aad7338f426162c889a 100644 --- a/gcc/testsuite/gfortran.dg/generic_14.f90 +++ b/gcc/testsuite/gfortran.dg/generic_14.f90 @@ -85,18 +85,18 @@ end module f module g implicit none - external wrong_b ! { dg-error "has no explicit interface" } + external wrong_b interface gen_wrong_5 - module procedure wrong_b ! wrong, see above + module procedure wrong_b ! { dg-error "has no explicit interface" } end interface gen_wrong_5 end module g module h implicit none - external wrong_c ! { dg-error "has no explicit interface" } + external wrong_c real wrong_c interface gen_wrong_6 - module procedure wrong_c ! wrong, see above + module procedure wrong_c ! { dg-error "has no explicit interface" } end interface gen_wrong_6 end module h diff --git a/gcc/testsuite/gfortran.dg/module_procedure_1.f90 b/gcc/testsuite/gfortran.dg/module_procedure_1.f90 new file mode 100644 index 0000000000000000000000000000000000000000..5e1fa15c729fcffb32f8ce241a0e05c5e4484ac9 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/module_procedure_1.f90 @@ -0,0 +1,53 @@ +! { dg-do run } +! Modified program from http://groups.google.com/group/\ +! comp.lang.fortran/browse_frm/thread/423e4392dc965ab7# +! +module myoperator + contains + function dadd(arg1,arg2) + integer ::dadd(2) + integer, intent(in) :: arg1(2), arg2(2) + dadd(1)=arg1(1)+arg2(1) + dadd(2)=arg1(2)+arg2(2) + end function dadd +end module myoperator + +program test_interface + + use myoperator + + implicit none + + interface operator (.myadd.) + module procedure dadd + end interface + + integer input1(2), input2(2), mysum(2) + + input1 = (/0,1/) + input2 = (/3,3/) + mysum = input1 .myadd. input2 + if (mysum(1) /= 3 .and. mysum(2) /= 4) call abort + + call test_sub(input1, input2) + +end program test_interface + +subroutine test_sub(input1, input2) + + use myoperator + + implicit none + + interface operator (.myadd.) + module procedure dadd + end interface + + integer, intent(in) :: input1(2), input2(2) + integer mysum(2) + + mysum = input1 .myadd. input2 + if (mysum(1) /= 3 .and. mysum(2) /= 4) call abort + +end subroutine test_sub +! { dg-final { cleanup-modules "myoperator" } } diff --git a/gcc/testsuite/gfortran.dg/module_procedure_2.f90 b/gcc/testsuite/gfortran.dg/module_procedure_2.f90 new file mode 100644 index 0000000000000000000000000000000000000000..8f6db25fb13d6434c536376c834644475adadeea --- /dev/null +++ b/gcc/testsuite/gfortran.dg/module_procedure_2.f90 @@ -0,0 +1,8 @@ +! { dg-do compile } +program test + implicit none + intrinsic sin + interface gen2 + module procedure sin ! { dg-error "cannot be a MODULE PROCEDURE" } + end interface gen2 +end program test