Dear All, I had noticed this bug when writing submodule_14.f08 but promptly forgot all about it. The fix is trivial. The error checks for pure and elemental have been inverted to prevent missing elemental prefixes being flagged as missing pure prefixes. This arises from the implicit pure attribute given to elemental procedures.
Bootstrapped and regtested on FC21/x86_64 - OK for trunk and 6-branch? Paul 2016-06-01 Paul Thomas <pa...@gcc.gnu.org> PR fortran/71156 * decl.c (copy_prefix): Add checks that the module procedure declaration prefixes are compliant with the interface. Invert order of existing elemental and pure checks. * resolve.c (resolve_fl_procedure): Invert order of elemental and pure errors. 2016-06-01 Paul Thomas <pa...@gcc.gnu.org> PR fortran/71156 * gfortran.dg/submodule_14.f08: Add missing recursive prefix to the module procedure declaration. * gfortran.dg/submodule_16.f08: New test
Index: gcc/fortran/decl.c =================================================================== *** gcc/fortran/decl.c (revision 236356) --- gcc/fortran/decl.c (working copy) *************** error: *** 4978,4989 **** static bool copy_prefix (symbol_attribute *dest, locus *where) { ! if (current_attr.pure && !gfc_add_pure (dest, where)) return false; if (current_attr.elemental && !gfc_add_elemental (dest, where)) return false; if (current_attr.recursive && !gfc_add_recursive (dest, where)) return false; --- 4978,5028 ---- static bool copy_prefix (symbol_attribute *dest, locus *where) { ! if (dest->module_procedure) ! { ! if (current_attr.elemental) ! dest->elemental = 1; ! ! if (current_attr.pure) ! dest->pure = 1; ! ! if (current_attr.recursive) ! dest->recursive = 1; ! ! /* Module procedures are unusual in that the 'dest' is copied from ! the interface declaration. However, this is an oportunity to ! check that the submodule declaration is compliant with the ! interface. */ ! if (dest->elemental && !current_attr.elemental) ! { ! gfc_error ("ELEMENTAL prefix in MODULE PROCEDURE interface is " ! "missing at %L", where); return false; + } + + if (dest->pure && !current_attr.pure) + { + gfc_error ("PURE prefix in MODULE PROCEDURE interface is " + "missing at %L", where); + return false; + } + + if (dest->recursive && !current_attr.recursive) + { + gfc_error ("RECURSIVE prefix in MODULE PROCEDURE interface is " + "missing at %L", where); + return false; + } + + return true; + } if (current_attr.elemental && !gfc_add_elemental (dest, where)) return false; + if (current_attr.pure && !gfc_add_pure (dest, where)) + return false; + if (current_attr.recursive && !gfc_add_recursive (dest, where)) return false; Index: gcc/fortran/resolve.c =================================================================== *** gcc/fortran/resolve.c (revision 236356) --- gcc/fortran/resolve.c (working copy) *************** resolve_fl_procedure (gfc_symbol *sym, i *** 11965,11981 **** goto check_formal; /* Check the procedure characteristics. */ ! if (sym->attr.pure != iface->attr.pure) { ! gfc_error ("Mismatch in PURE attribute between MODULE " "PROCEDURE at %L and its interface in %s", &sym->declared_at, module_name); return false; } ! if (sym->attr.elemental != iface->attr.elemental) { ! gfc_error ("Mismatch in ELEMENTAL attribute between MODULE " "PROCEDURE at %L and its interface in %s", &sym->declared_at, module_name); return false; --- 11965,11981 ---- goto check_formal; /* Check the procedure characteristics. */ ! if (sym->attr.elemental != iface->attr.elemental) { ! gfc_error ("Mismatch in ELEMENTAL attribute between MODULE " "PROCEDURE at %L and its interface in %s", &sym->declared_at, module_name); return false; } ! if (sym->attr.pure != iface->attr.pure) { ! gfc_error ("Mismatch in PURE attribute between MODULE " "PROCEDURE at %L and its interface in %s", &sym->declared_at, module_name); return false; Index: gcc/testsuite/gfortran.dg/submodule_14.f08 =================================================================== *** gcc/testsuite/gfortran.dg/submodule_14.f08 (revision 236356) --- gcc/testsuite/gfortran.dg/submodule_14.f08 (working copy) *************** contains *** 27,33 **** Call sub1 (x) End If End Procedure sub1 ! module function fcn1 (x) result(res) integer, intent (inout) :: x integer :: res res = x - 1 --- 27,33 ---- Call sub1 (x) End If End Procedure sub1 ! recursive module function fcn1 (x) result(res) integer, intent (inout) :: x integer :: res res = x - 1 Index: gcc/testsuite/gfortran.dg/submodule_16.f08 =================================================================== *** gcc/testsuite/gfortran.dg/submodule_16.f08 (revision 0) --- gcc/testsuite/gfortran.dg/submodule_16.f08 (working copy) *************** *** 0 **** --- 1,53 ---- + ! { dg-do compile } + ! + ! Tests the fix for PR71156 in which the valid code (f7, f8 and f9 below) + ! triggered an error, while the invalid code (f1 to f6) compiled. + ! + ! Contributed by Damian Rousn <dam...@sourceryinstitute.org> + ! + module my_interface + implicit none + interface + module subroutine f1 + end subroutine + module subroutine f2 + end subroutine + module subroutine f3 + end subroutine + elemental module subroutine f4 + end subroutine + pure module subroutine f5 + end subroutine + recursive module subroutine f6 + end subroutine + elemental module subroutine f7 + end subroutine + pure module subroutine f8 + end subroutine + recursive module subroutine f9 + end subroutine + end interface + end module + + submodule(my_interface) my_implementation + implicit none + contains + elemental module subroutine f1 ! { dg-error "Mismatch in ELEMENTAL attribute" } + end subroutine + pure module subroutine f2 ! { dg-error "Mismatch in PURE attribute" } + end subroutine + recursive module subroutine f3 ! { dg-error "Mismatch in RECURSIVE attribute" } + end subroutine + module subroutine f4 ! { dg-error "ELEMENTAL prefix" } + end subroutine + module subroutine f5 ! { dg-error "PURE prefix" } + end subroutine + module subroutine f6 ! { dg-error "RECURSIVE prefix" } + end subroutine + elemental module subroutine f7 + end subroutine + pure module subroutine f8 + end subroutine + recursive module subroutine f9 + end subroutine + end submodule