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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
+ !
+ 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