Bug 47565 - [4.6 Regression][OOP] Segfault with TBP
[4.6 Regression][OOP] Segfault with TBP
Status: RESOLVED FIXED
Product: gcc
Classification: Unclassified
Component: fortran
4.6.0
: P3 normal
: ---
Assigned To: janus
: wrong-code
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2011-02-01 08:49 UTC by Tobias Burnus
Modified: 2011-02-02 18:15 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2011-02-01 13:00:47


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Burnus 2011-02-01 08:49:02 UTC
Follow up to bug 47455 comment 4.

The following program works with gfortran 4.5 but with gfortran 4.6 it segfaults at run time at the marked line.

Using a normal function call instead of a TBP call works as well.

==20391== Jump to the invalid address stated on the next line
==20391==    at 0x0: ???
==20391==    by 0x400C49: MAIN__ (444.f90:27)
==20391==    by 0x400C7F: main (444.f90:25)


The dump shows the following difference between working and failing:
-    this->_data->y = *find_y ();
+    this->_data->y = *this->_vptr->find_y ();

If one compares this with a working call and POINTER attribute (cf. attachment 23130 [details] to bug 47455 comment 4), one sees:

! Working:
  this->_data->x = this->_vptr->find_x (...)
! Failing:
  this->_data->y = *this->_vptr->find_y (...)

Note the extra "*".


module class_t
    type :: tx
        integer, dimension(:), allocatable :: i
    end type tx
    type :: t
        type(tx) :: y
    contains
        procedure :: calc
        procedure, nopass :: find_y
    end type t
contains
    subroutine calc(this)
        class(t) :: this
! WORKS:
!       this%y = find_y()
! Segfaults:
       this%y = this%find_y() ! Segfault at run time
        print *, allocated(this%y%i)
    end subroutine calc
    function find_y() result(res)
        type(tx), allocatable :: res
        allocate(res)
   end function find_y
end module class_t
use class_t
type(t) :: x
call x%calc()
end
Comment 1 janus 2011-02-01 13:00:47 UTC
Modified test case:


module class_t
contains
  function find_y() result(res)
    integer, allocatable :: res
    print *,"find_y"
    allocate(res)
  end function
end module

program p
  use class_t
  type :: t
    procedure(find_y), pointer, nopass :: ppc
  contains
    procedure, nopass :: find_y
  end type
  class(t), allocatable :: this
  integer :: y

  allocate(this)
  this%ppc => find_y
  ! (1) ordinary procedure (works)
  y = find_y()
  print *, y
  ! (2) procedure pointer component (works)
  y = this%ppc()
  print *, y
  ! (3) type-bound procedure (fails)
  y = this%find_y()  ! segfault at run time
  print *, y
end 


This shows that the PPC call also works nicely, while the TBP does not.
The dump for all three calls looks ok:

      y = *find_y ();
      y = *this._data->ppc ();
      y = *this._vptr->find_y ();

The problem seems to be that the initialization for the TBP is missing in the vtab:

  static struct __vtype_p_T __vtab_p_T = {._hash=31520549, ._size=8, ._extends=0B, ._def_init=&__def_init_p_T, ._copy=__copy_p_T};

When removing the allocatable attribute of 'find_y', one correctly gets:

  static struct __vtype_p_T __vtab_p_T = {._hash=31520549, ._size=8, ._extends=0B, ._def_init=&__def_init_p_T, ._copy=__copy_p_T, .find_y=find_y};
Comment 2 janus 2011-02-01 13:39:31 UTC
Here is the obvious fix:


Index: trans-expr.c
===================================================================
--- trans-expr.c        (revision 169470)
+++ trans-expr.c        (working copy)
@@ -4627,7 +4627,7 @@ gfc_conv_structure (gfc_se * se, gfc_expr * expr,
         components.  Although the latter have a default initializer
         of EXPR_NULL,... by default, the static nullify is not needed
         since this is done every time we come into scope.  */
-      if (!c->expr || cm->attr.allocatable)
+      if (!c->expr || (cm->attr.allocatable && cm->attr.flavor != FL_PROCEDURE))
         continue;
 
       if (strcmp (cm->name, "_size") == 0)



Will commit after regtesting.
Comment 3 janus 2011-02-01 14:59:45 UTC
Author: janus
Date: Tue Feb  1 14:59:40 2011
New Revision: 169480

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

	PR fortran/47565
	* trans-expr.c (gfc_conv_structure): Handle constructors for procedure
	pointer components with allocatable result.


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

	PR fortran/47565
	* gfortran.dg/typebound_call_20.f03: New.

Added:
    trunk/gcc/testsuite/gfortran.dg/typebound_call_20.f03
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/trans-expr.c
    trunk/gcc/testsuite/ChangeLog
Comment 4 janus 2011-02-01 15:01:22 UTC
Fixed with r169480. Closing.
Comment 5 Diego Novillo 2011-02-02 18:15:41 UTC
Author: dnovillo
Date: Wed Feb  2 18:15:33 2011
New Revision: 169746

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

	PR fortran/47565
	* trans-expr.c (gfc_conv_structure): Handle constructors for procedure
	pointer components with allocatable result.


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

	PR fortran/47565
	* gfortran.dg/typebound_call_20.f03: New.

Added:
    branches/google/integration/gcc/testsuite/gfortran.dg/typebound_call_20.f03
Modified:
    branches/google/integration/gcc/fortran/ChangeLog
    branches/google/integration/gcc/fortran/trans-expr.c
    branches/google/integration/gcc/testsuite/ChangeLog