Bug 40176 - Fortran 2003: Procedure pointers with array return value
Summary: Fortran 2003: Procedure pointers with array return value
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.5.0
: P3 normal
Target Milestone: ---
Assignee: janus
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2009-05-17 14:07 UTC by janus
Modified: 2009-06-12 20:45 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2009-05-18 16:59:25


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description janus 2009-05-17 14:07:04 UTC
The following program compiles without errors, but gives a segfault at runtime:

PROGRAM test_prog

  PROCEDURE(triple), POINTER :: f

  ! This works
  print *,triple(2.,4.)

  ! This creates a Segmentation Fault
  f => triple
  print *,f(2.,4.)

CONTAINS
 
  FUNCTION triple(a,b) RESULT(tre)
    REAL, INTENT(in) :: a, b
    REAL :: tre(2)
    tre(1) = 3.*a
    tre(2) = 3.*b
  END FUNCTION triple

END PROGRAM test_prog

Reported by Barron Bichon.
Comment 1 janus 2009-05-17 14:13:15 UTC
-fdump-parse-tree yields:

triple (struct array1_real(kind=4) & __result, real(kind=4) & a, real(kind=4) & b)
{
...
}

  real(kind=4) (*<T3e0>) (real(kind=4) &, real(kind=4) &) f;

  f = (real(kind=4) (*<T3e0>) (real(kind=4) &, real(kind=4) &)) triple;

So it seems like something goes wrong in the declaration of 'f', (which should be equal to 'triple')?!?
Comment 2 janus 2009-05-18 12:28:06 UTC
This test case with 'dynamic' array size produces a gimplification error:

PROGRAM test_prog

 ABSTRACT INTERFACE
 FUNCTION fn_template(n,x) RESULT(y)
   INTEGER, INTENT(in) :: n
   REAL, INTENT(in) :: x(n)
   REAL :: y(n)
 END FUNCTION fn_template
 END INTERFACE

 TYPE ProcPointerArray
   PROCEDURE(fn_template), POINTER, NOPASS :: f
 END TYPE ProcPointerArray

 TYPE (ProcPointerArray) :: f_array(1)
 PROCEDURE(fn_template), POINTER :: f
 REAL :: tre(2)

 f_array(1)%f => triple		! gimplification error
 f => f_array(1)%f
 tre = f(2,[2.,4.])
 PRINT*, tre

CONTAINS

 FUNCTION triple(n,x) RESULT(tre)
   INTEGER, INTENT(in) :: n
   REAL, INTENT(in) :: x(n)
   REAL :: tre(n)
   tre = 3.*x
 END FUNCTION triple

END PROGRAM test_prog
Comment 3 janus 2009-05-18 16:59:25 UTC
Comment #0 is fixed by the following one-liner patch:

Index: gcc/fortran/resolve.c
===================================================================
--- gcc/fortran/resolve.c	(revision 147663)
+++ gcc/fortran/resolve.c	(working copy)
@@ -9414,6 +9414,7 @@
 	  || sym->ts.interface->attr.intrinsic)
 	{
 	  gfc_symbol *ifc = sym->ts.interface;
+	  resolve_symbol (ifc);
 
 	  if (ifc->attr.intrinsic)
 	    resolve_intrinsic (ifc, &ifc->declared_at);

However this does nothing about the gimplification failure in comment #2.
Comment 4 janus 2009-05-25 14:48:41 UTC
Subject: Bug 40176

Author: janus
Date: Mon May 25 14:48:24 2009
New Revision: 147850

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=147850
Log:
2009-05-25  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/40176
	* primary.c (gfc_match_varspec): Handle procedure pointer components
	with array return value.
	* resolve.c (resolve_expr_ppc): Ditto.
	(resolve_symbol): Make sure the interface of a procedure pointer has
	been resolved.
	* trans-array.c (gfc_walk_function_expr): Handle procedure pointer
	components with array return value.
	* trans-expr.c (gfc_conv_component_ref,gfc_conv_procedure_call,
	gfc_trans_arrayfunc_assign): Ditto.
	(gfc_trans_pointer_assignment): Handle procedure pointer assignments,
	where the rhs is a dummy argument.
	* trans-types.c (gfc_get_ppc_type,gfc_get_derived_type): Handle
	procedure pointer components with array return value.


2009-05-25  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/40176
	* gfortran.dg/proc_ptr_18.f90: New.
	* gfortran.dg/proc_ptr_19.f90: New.
	* gfortran.dg/proc_ptr_comp_9.f90: New.
	* gfortran.dg/proc_ptr_comp_10.f90: New.


Added:
    trunk/gcc/testsuite/gfortran.dg/proc_ptr_18.f90
    trunk/gcc/testsuite/gfortran.dg/proc_ptr_19.f90
    trunk/gcc/testsuite/gfortran.dg/proc_ptr_comp_10.f90
    trunk/gcc/testsuite/gfortran.dg/proc_ptr_comp_9.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/primary.c
    trunk/gcc/fortran/resolve.c
    trunk/gcc/fortran/trans-array.c
    trunk/gcc/fortran/trans-expr.c
    trunk/gcc/fortran/trans-types.c
    trunk/gcc/testsuite/ChangeLog

Comment 5 Dominique d'Humieres 2009-05-25 20:05:58 UTC
The following invalid code (reduced from the original code):

! { dg-do compile }
! This tests various error messages for PROCEDURE declarations.
! Contributed by Janus Weil <jaydub66@gmail.com>

program prog

contains

  subroutine foo(a,c)
    procedure(c),intent(in):: c  ! { dg-error "PROCEDURE attribute conflicts with INTENT attribute" }
  end subroutine foo 

end program

seems stuck in an infinite loop (r147851 + '-fwhole-file' patch):

ibook-dhum] f90/bug% gfc proc_decl_1_red.f90
proc_decl_1_red.f90:9.20:

  subroutine foo(a,c)
                    1
Error: Interface 'c', used by procedure 'c' at (1), is declared in a later PROCEDURE statement
proc_decl_1_red.f90:9.20:

  subroutine foo(a,c)
                    1
Error: Interface 'c', used by procedure 'c' at (1), is declared in a later PROCEDURE statement
proc_decl_1_red.f90:9.20:

  subroutine foo(a,c)
                    1
Error: Interface 'c', used by procedure 'c' at (1), is declared in a later PROCEDURE statement
proc_decl_1_red.f90:9.20:

  subroutine foo(a,c)
                    1
Error: Interface 'c', used by procedure 'c' at (1), is declared in a later PROCEDURE statement
proc_decl_1_red.f90:9.20:

  subroutine foo(a,c)
                    1
Error: Interface 'c', used by procedure 'c' at (1), is declared in a later PROCEDURE statement
proc_decl_1_red.f90:9.20:

  subroutine foo(a,c)
                    1
Error: Interface 'c', used by procedure 'c' at (1), is declared in a later PROCEDURE statement
proc_decl_1_red.f90:9.20:

  subroutine foo(a,c)
                    1
Error: Interface 'c', used by procedure 'c' at (1), is declared in a later PROCEDURE statement
proc_decl_1_red.f90:9.20:

  subroutine foo(a,c)
                    1
Error: Interface 'c', used by procedure 'c' at (1), is declared in a later PROCEDURE statement
proc_decl_1_red.f90:9.20:

  subroutine foo(a,c)
                    1
Error: Interface 'c', used by procedure 'c' at (1), is declared in a later PROCEDURE statement
proc_decl_1_red.f90:9.20:

  subroutine foo(a,c)
                    1
Error: Interface 'c', used by procedure 'c' at (1), is declared in a later PROCEDURE statement
proc_decl_1_red.f90:9.20:

  subroutine foo(a,c)
                    1
Error: Interface 'c', used by procedure 'c' at (1), is declared in a later PROCEDURE statement
proc_decl_1_red.f90:9.20:

  subroutine foo(a,c)
                    1
Error: Interface 'c', used by procedure 'c' at (1), is declared in a later PROCEDURE statement
proc_decl_1_red.f90:9.20:

  subroutine foo(a,c)
                    1
Error: Interface 'c', used by procedure 'c' at (1), is declared in a later PROCEDURE statement
proc_decl_1_red.f90:9.20:

  subroutine foo(a,c)
                    1
Error: Interface 'c', used by procedure 'c' at (1), is declared in a later PROCEDURE statement
proc_decl_1_red.f90:9.20:

  subroutine foo(a,c)
                    1
Error: Interface 'c', used by procedure 'c' at (1), is declared in a later PROCEDURE statement
proc_decl_1_red.f90:9.20:

  subroutine foo(a,c)
                    1
Error: Interface 'c', used by procedure 'c' at (1), is declared in a later PROCEDURE statement
proc_decl_1_red.f90:9.20:

  subroutine foo(a,c)
                    1
Error: Interface 'c', used by procedure 'c' at (1), is declared in a later PROCEDURE statement
proc_decl_1_red.f90:9.20:

  subroutine foo(a,c)
                    1
Error: Interface 'c', used by procedure 'c' at (1), is declared in a later PROCEDURE statement
proc_decl_1_red.f90:9.20:

  subroutine foo(a,c)
                    1
Error: Interface 'c', used by procedure 'c' at (1), is declared in a later PROCEDURE statement
proc_decl_1_red.f90:9.20:

  subroutine foo(a,c)
                    1
Error: Interface 'c', used by procedure 'c' at (1), is declared in a later PROCEDURE statement
proc_decl_1_red.f90:9.20:

  subroutine foo(a,c)
                    1
Error: Interface 'c', used by procedure 'c' at (1), is declared in a later PROCEDURE statement
proc_decl_1_red.f90:9.20:

  subroutine foo(a,c)
                    1
Error: Interface 'c', used by procedure 'c' at (1), is declared in a later PROCEDURE statement
proc_decl_1_red.f90:9.20:

  subroutine foo(a,c)
                    1
Error: Interface 'c', used by procedure 'c' at (1), is declared in a later PROCEDURE statement
proc_decl_1_red.f90:9.20:

  subroutine foo(a,c)
                    1
Error: Interface 'c', used by procedure 'c' at (1), is declared in a later PROCEDURE statement
proc_decl_1_red.f90:9.20:

  subroutine foo(a,c)
                    1
Error: Interface 'c', used by procedure 'c' at (1), is declared in a later PROCEDURE statement
Fatal Error: Error count reached limit of 25.
Comment 6 Dominique d'Humieres 2009-05-27 14:08:52 UTC
The infinite loop in comment #5 can be seen without the -fwhole-file flag (see comment #22 in pr40011).

Comment 7 janus 2009-06-12 20:39:59 UTC
Subject: Bug 40176

Author: janus
Date: Fri Jun 12 20:39:39 2009
New Revision: 148440

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=148440
Log:
2009-06-12  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/40176
	* resolve.c (resolve_symbol): Additional error check, preventing an
	infinite loop.


2009-06-12  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/40176
	* gfortran.dg/proc_decl_1.f90: Extended.


Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/resolve.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gfortran.dg/proc_decl_1.f90

Comment 8 janus 2009-06-12 20:45:47 UTC
The remaining issue from comment #5 has been fixed with the commit in comment #7. So this can be closed.