http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51378

             Bug #: 51378
           Summary: [OOP] Structure constructor wrongly rejects parent
                    components if only child has PRIVATE comps
    Classification: Unclassified
           Product: gcc
           Version: 4.7.0
            Status: UNCONFIRMED
          Keywords: rejects-valid
          Severity: normal
          Priority: P3
         Component: fortran
        AssignedTo: unassig...@gcc.gnu.org
        ReportedBy: bur...@gcc.gnu.org
                CC: ja...@gcc.gnu.org


Found in Reinhold Bader's testsuite (partial_construct_01_pos.f90). The
following program is rejected by crayftn and gfortran with:

  Derived type "L_VEC" has private components, therefore a structure
constructor must not be defined for this type.

and with 

  o_l_vec = l_vec(comp=(/1.0, 2.0, 3.0/),len=3)
            1
  Error: Component 'comp' at (1) is a PRIVATE component of 'l_vec'

The program is accepted by ifort 12. The question is whether "COMP" and "LEN"
are private or not. If they are not and only "label" is private, the program is
valid as the following is not violated (quote from F2008):

"C495 (R455) The type name and all components of the type for which a
component-spec appears shall be accessible in the scoping unit containing the
structure constructor."

And the following guarantees that they remain accessible even if the extension
uses a "PRIVATE" statement:

"4.5.7.2 Inheritance
An extended type includes all of the type parameters, all of the components,
and the nonoverridden (4.5.7.3) type-bound procedures of its parent type. These
are inherited by the extended type from the parent type. They retain all of the
attributes that they had in the parent type."


module type_ext
  type :: vec
     real, dimension(3) :: comp
     integer :: len
  end type vec
  type, extends(vec) :: l_vec
     private
     character(len=20) :: label = '01234567890123456789'
  end type l_vec
end module type_ext
program test_ext
  use type_ext
  implicit none
  type(vec) :: o_vec, oo_vec
  type(l_vec) :: o_l_vec
  integer :: i
!
  o_vec = vec((/1.0, 2.0, 3.0/),3)
!  write(*,*) o_vec%comp, o_vec%len
  o_l_vec = l_vec(comp=(/1.0, 2.0, 3.0/),len=3)
! partial constr. not accepted by ifort 11.1, fixed in 12.0 (issue 562240)
!  write(*,*) o_l_vec%comp, o_l_vec%len
!  write(*,*) o_l_vec%vec
  oo_vec = o_l_vec%vec
  do i=1, 3
    if (abs(oo_vec%comp(i) - o_vec%comp(i)) > 1.0E-5) then
       write(*, *) 'FAIL'
       stop
    end if
  end do
  write(*, *) 'OK'
end program

Reply via email to