Bug 47352 - [F03] ICE with proc-pointers in generic procedures
Summary: [F03] ICE with proc-pointers in generic procedures
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.6.0
: P3 normal
Target Milestone: ---
Assignee: janus
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2011-01-18 21:17 UTC by Tobias Burnus
Modified: 2011-02-09 23:00 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2011-01-18 23:39:08


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Burnus 2011-01-18 21:17:01 UTC
Found at http://groups.google.com/group/comp.lang.fortran/browse_thread/thread/bbaf59ffd7c372e9#  (There is another issue in that thread)

The following program causes an ICE with gfortran in:

==779== Invalid read of size 1
==779==    at 0x58B717: gfc_conv_expr_reference (trans-expr.c:4839)
==779==    by 0x5A400B: gfc_trans_transfer (trans-io.c:2328)
==779==    by 0x565607: trans_code (trans.c:1371)


Reduced (and w/o comments) full test case:

module mytypes
   implicit none
   abstract interface
      function f(x)
         real f, x
      end function f
!      function g(x)
!         integer g, x
!      end function g
   end interface
   procedure(f),pointer,save :: f1
!   procedure(g),pointer,save :: g1
   interface gen
      procedure f1!,g1
   end interface gen
end module mytypes

!module funcs
!   implicit none
!   contains
!      function f(x)
!         real f, x
!         f = 3*x
!      end function f
!      function g(x)
!         integer g, x
!         g = 3*x
!      end function g
!end module funcs

program test
   use mytypes
!   use funcs, f2=>f, g2=>g
   implicit none

!   f1 => f2
!   g1 => g2
!   write(*,*) gen(1)
   write(*,*) gen(1.0)
end program test
Comment 1 janus 2011-01-18 23:39:08 UTC
Confirmed. Note: The ICE already happens with a simple PROCEDURE statement without the POINTER attribute:


   implicit none

   abstract interface
      real function f()
      end function f
   end interface

   procedure(f) :: f1

   interface gen
      procedure f1
   end interface gen

   write(*,*) gen()    ! ICE
end


At first I was not quite sure if the code in comment #0 is valid, but F08 chapter 12.4.3.4.1 explicitly lists procedure pointers as being allowed in a generic interface.
Comment 2 Tobias Burnus 2011-01-19 15:58:28 UTC
(In reply to comment #0)
> Found at http://groups.google.com/group/comp.lang.fortran/browse_thread/thread/bbaf59ffd7c372e9#
>  (There is another issue in that thread)

The other issue involving proc-pointer components and a GENERIC type-bound procedure is now tracked as PR 47360.
Comment 3 janus 2011-01-19 21:21:30 UTC
Simple patch to avoid the ICE:

Index: gcc/fortran/trans-expr.c
===================================================================
--- gcc/fortran/trans-expr.c	(revision 168973)
+++ gcc/fortran/trans-expr.c	(working copy)
@@ -4827,7 +4827,7 @@ gfc_conv_expr_reference (gfc_se * se, gfc_expr * e
     }
 
   if (expr->expr_type == EXPR_FUNCTION
-      && ((expr->value.function.esym
+      && ((expr->value.function.esym && expr->value.function.esym->result
 	   && expr->value.function.esym->result->attr.pointer
 	   && !expr->value.function.esym->result->attr.dimension)
 	  || (!expr->value.function.esym
Comment 4 janus 2011-01-21 23:01:23 UTC
(In reply to comment #3)
> Simple patch to avoid the ICE:

The patch in comment #3 regtests without problems. However, I'm not sure if it's the best solution. Here is an alternative:

Index: gcc/fortran/resolve.c
===================================================================
--- gcc/fortran/resolve.c       (revision 169052)
+++ gcc/fortran/resolve.c       (working copy)
@@ -167,6 +167,8 @@ resolve_procedure_interface (gfc_symbol *sym)
       sym->attr.function = ifc->attr.function;
       sym->attr.subroutine = ifc->attr.subroutine;
       gfc_copy_formal_args (sym, ifc);
+      if (sym->attr.function)
+       sym->result = sym;
 
       sym->attr.allocatable = ifc->attr.allocatable;
       sym->attr.pointer = ifc->attr.pointer;
Comment 5 janus 2011-01-22 17:48:04 UTC
(In reply to comment #4)
> Index: gcc/fortran/resolve.c
> ===================================================================
> --- gcc/fortran/resolve.c       (revision 169052)
> +++ gcc/fortran/resolve.c       (working copy)
> @@ -167,6 +167,8 @@ resolve_procedure_interface (gfc_symbol *sym)
>        sym->attr.function = ifc->attr.function;
>        sym->attr.subroutine = ifc->attr.subroutine;
>        gfc_copy_formal_args (sym, ifc);
> +      if (sym->attr.function)
> +       sym->result = sym;
> 
>        sym->attr.allocatable = ifc->attr.allocatable;
>        sym->attr.pointer = ifc->attr.pointer;


This one also regtests cleanly, and I think it is preferable over the previous one.
Comment 6 janus 2011-02-09 22:00:21 UTC
Here is yet another variant:

Index: gcc/fortran/resolve.c
===================================================================
--- gcc/fortran/resolve.c	(revision 169985)
+++ gcc/fortran/resolve.c	(working copy)
@@ -160,7 +160,10 @@ resolve_procedure_interface (gfc_symbol *sym)
 	resolve_intrinsic (ifc, &ifc->declared_at);
 
       if (ifc->result)
-	sym->ts = ifc->result->ts;
+	{
+	  sym->ts = ifc->result->ts;
+	  sym->result = sym;
+	}
       else   
 	sym->ts = ifc->ts;
       sym->ts.interface = ifc;


This has basically the same effect as the one in comment #4, but it'a a bit clearer.

I'd even say it's pretty much obvious in this form. Will commit after regtesting.
Comment 7 janus 2011-02-09 22:59:08 UTC
Author: janus
Date: Wed Feb  9 22:59:02 2011
New Revision: 169987

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=169987
Log:
2011-02-09  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/47352
	* resolve.c (resolve_procedure_interface): If interface has a result
	variable, copy the typespec and set result pointer to self.


2011-02-09  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/47352
	* gfortran.dg/proc_decl_25.f90: New.

Added:
    trunk/gcc/testsuite/gfortran.dg/proc_decl_25.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/resolve.c
    trunk/gcc/testsuite/ChangeLog
Comment 8 janus 2011-02-09 23:00:30 UTC
Fixed with r169987. Closing.