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

Reply via email to