Bug 44541 - [OOP] wrong code for polymorphic variable with INTENT(OUT)/Alloc w/ MOLD
[OOP] wrong code for polymorphic variable with INTENT(OUT)/Alloc w/ MOLD
Status: RESOLVED FIXED
Product: gcc
Classification: Unclassified
Component: fortran
4.6.0
: P3 normal
: ---
Assigned To: janus
: wrong-code
Depends on: 43388
Blocks:
  Show dependency treegraph
 
Reported: 2010-06-15 07:45 UTC by Tobias Burnus
Modified: 2010-09-01 21:25 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2010-08-29 21:10:26


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Burnus 2010-06-15 07:45:00 UTC
Follow up to PR 43388 (ALLOCATE with MOLD, a F2008 feature), but it also applies to polymorphic variables with INTENT(OUT) (i.e. to F2003).

In either cases, a potentially existing default initializer of the *effective type* needs to be applied. That means that this data has to be available in the vtable.

See also: http://j3-fortran.org/pipermail/j3/2010-June/003621.html

(Thanks to Janus for spotting the problem (for MOLD) at the first place; thanks to Bill Long for confirmation and mentioning INTENT(OUT); and to Aleksandar Donev for the comments.)

Testing shows that other vendors have also overlooked these cases.
(For intent out, there seem to be compiler which do not set the variable at all (e.g. gfortran) or those which only use the base type for the initialization; similarly, for MOLD where unspecified initialization happens (via malloc), possibly with base-type initialization on top.)

---------- INTENT(OUT) test case -----------------
! Expected: a= 1  b= 3
  implicit none
  type t
    integer :: a = 1
  end type t
  type, extends(t) :: t2
    integer :: b = 3
  end type t2

  type(t2) :: y
  y%a = 44
  y%b = 55
  call intent_out (y)
  print *, 'a=', y%a, ' b=', y%b
contains
  subroutine intent_out(x)
    class(t), intent(out) :: x
    select type (x)
      type is (t2)
      print *, 'a=', x%a, ' b=', x%b
    end select
  end subroutine
end

---------- MOLD test case ------------------------
! Expected:
!  a= 1  b= 3
! (Wrong is "a= 1  b= 0" or "a= 0  b= 0" or garbage)
implicit none
type t
  integer :: a = 1
end type t

type, extends(t) :: t2
  integer :: b = 3
end type t2

class(t), allocatable :: x, y

allocate (t2 :: y)
select type (y)
  type is (t2)
    y%a = 44
    y%b = 55
end select

allocate ( x, mold=y)
select type (x)
  type is (t2)
   print *, 'a=', x%a, ' b=', x%b
end select
end
Comment 1 janus 2010-06-15 18:40:31 UTC
(In reply to comment #0)
> Follow up to PR 43388 (ALLOCATE with MOLD, a F2008 feature)


For the MOLD problem we already have a test case in allocate_alloc_opt_10.f90 (which is put behind comments right now, but should be uncommented once this PR is fixed).
Comment 2 janus 2010-06-21 10:18:30 UTC
My first idea to fix this was to add a new field to the vtabs, let's call it $def_init, which would be the fourth field in the vtab structure (after $hash, $size and $extends), and would contain the default initialization values for the type.

However, this approach does not work, since the field needed for default initialization would have to be of the derived type which the vtab belongs to. This however can have different sizes, so that the PPCs in the vtab will not be aligned any more for extended types, which messes up dynamic dispatch.

Alternatives:
(1) make $def_init a pointer (problem: initialization of $def_init itself)
(2) add standalone variables a la "type_t$def_init" to carry default initialization for each type
(3) ...?
Comment 3 Tobias Burnus 2010-08-21 12:51:29 UTC
Is this now fixable using the default pointer initialization?
Comment 4 janus 2010-08-21 15:14:32 UTC
(In reply to comment #3)
> Is this now fixable using the default pointer initialization?

At least pointer initialization enables us to initalize the $def_init pointer component. But still we will need a default-initialized variable which $def_init can point to.

The question is if we even need a $def_init component in the vtab (I think the answer is yes, since we don't know the dynamic type to use for initialization in the general case).
Comment 5 janus 2010-08-29 21:10:26 UTC
Mine (working on a patch).
Comment 6 janus 2010-09-01 20:51:03 UTC
Subject: Bug 44541

Author: janus
Date: Wed Sep  1 20:50:46 2010
New Revision: 163744

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

	PR fortran/44541
	* class.c (gfc_find_derived_vtab): Add component '$def_init'.
	* resolve.c (resolve_allocate_expr): Defer handling of default
	initialization to 'gfc_trans_allocate'.
	(apply_default_init,resolve_symbol): Handle polymorphic dummies.
	(resolve_fl_derived): Suppress error messages for vtypes.
	* trans-stmt.c (gfc_trans_allocate): Handle initialization via
	polymorphic MOLD expression.
	* trans-expr.c (gfc_trans_class_init_assign): Now only used for
	dummy initialization.


2010-09-01  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/44541
	* gfortran.dg/allocate_alloc_opt_10.f90: Extended.
	* gfortran.dg/class_dummy_1.f03: New.

Added:
    trunk/gcc/testsuite/gfortran.dg/class_dummy_1.f03
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/class.c
    trunk/gcc/fortran/resolve.c
    trunk/gcc/fortran/trans-expr.c
    trunk/gcc/fortran/trans-stmt.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gfortran.dg/allocate_alloc_opt_10.f90

Comment 7 Tobias Burnus 2010-09-01 21:25:05 UTC
Close as fixed (on the 4.6 trunk).

Thanks for the patch, Janus!
Comment 8 janus 2010-09-02 12:34:46 UTC
Subject: Bug 44541

Author: janus
Date: Thu Sep  2 12:34:26 2010
New Revision: 163773

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

	PR fortran/44541
	* resolve.c (resolve_symbol): Correct check for attributes of CLASS
	variable.

Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/resolve.c