summaryrefslogtreecommitdiff
path: root/gcc/testsuite/gfortran.dg/extends_1.f03
blob: 57a50732c559d4e952f4270c1d1e34e9ddd851a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
! { dg-do run }
! A basic functional test of derived type extension.
!
! Contributed by Paul Thomas  <pault@gcc.gnu.org>
!
module persons
  type :: person
    character(24) :: name = ""
    integer :: ss = 1
  end type person
end module persons

module person_education
  use persons
  type, extends(person) :: education
    integer ::  attainment = 0
    character(24) :: institution = ""
  end type education
end module person_education

  use person_education
  type, extends(education) :: service
    integer :: personnel_number = 0
    character(24) :: department = ""
  end type service
  
  type, extends(service) :: person_record
    type (person_record), pointer :: supervisor => NULL ()
  end type person_record
  
  type(person_record), pointer :: recruit, supervisor
  
! Check that references by ultimate component work

  allocate (supervisor)
  supervisor%name = "Joe Honcho"
  supervisor%ss = 123455
  supervisor%attainment = 100
  supervisor%institution = "Celestial University"
  supervisor%personnel_number = 1
  supervisor%department = "Directorate"

  recruit => entry ("John Smith", 123456, 1, "Bog Hill High School", &
                    99, "Records", supervisor)

  if (trim (recruit%name) /= "John Smith") call abort
  if (recruit%name /= recruit%service%name) call abort
  if (recruit%supervisor%ss /= 123455) call abort
  if (recruit%supervisor%ss /= supervisor%person%ss) call abort

  deallocate (supervisor)
  deallocate (recruit)
contains
  function entry (name, ss, attainment, institution, &
                  personnel_number, department, supervisor) result (new_person)
    integer :: ss, attainment, personnel_number
    character (*) :: name, institution, department
    type (person_record), pointer :: supervisor, new_person

    allocate (new_person)

! Check mixtures of references
    new_person%person%name = name
    new_person%service%education%person%ss = ss
    new_person%service%attainment = attainment
    new_person%education%institution = institution
    new_person%personnel_number = personnel_number
    new_person%service%department = department
    new_person%supervisor => supervisor
  end function
end

! { dg-final { cleanup-modules "persons person_education" } }