| ! { dg-do run } |
| ! |
| ! Tests the fix for PR81758, in which the vpointer for 'ptr' in |
| ! function 'pointer_value' would be set to the vtable of the component |
| ! 'container' rather than that of the component 'vec_elem'. In this test |
| ! case it is ensured that there is a single typebound procedure for both |
| ! types, so that different values are returned. In the original problem |
| ! completely different procedures were involved so that a segfault resulted. |
| ! |
| ! Reduced from the original code of Dimitry Liakh <liakhdi@ornl.gov> by |
| ! Paul Thomas <pault@gcc.gnu.org> |
| ! |
| module types |
| type, public:: gfc_container_t |
| contains |
| procedure, public:: get_value => ContTypeGetValue |
| end type gfc_container_t |
| |
| !Element of a container: |
| type, public:: gfc_cont_elem_t |
| integer :: value_p |
| contains |
| procedure, public:: get_value => ContElemGetValue |
| end type gfc_cont_elem_t |
| |
| !Vector element: |
| type, extends(gfc_cont_elem_t), public:: vector_elem_t |
| end type vector_elem_t |
| |
| !Vector: |
| type, extends(gfc_container_t), public:: vector_t |
| type(vector_elem_t), allocatable, private :: vec_elem |
| end type vector_t |
| |
| type, public :: vector_iter_t |
| class(vector_t), pointer, private :: container => NULL() |
| contains |
| procedure, public:: get_vector_value => vector_Value |
| procedure, public:: get_pointer_value => pointer_value |
| end type |
| |
| contains |
| integer function ContElemGetValue (this) |
| class(gfc_cont_elem_t) :: this |
| ContElemGetValue = this%value_p |
| end function |
| |
| integer function ContTypeGetValue (this) |
| class(gfc_container_t) :: this |
| ContTypeGetValue = 0 |
| end function |
| |
| integer function vector_Value (this) |
| class(vector_iter_t) :: this |
| vector_value = this%container%vec_elem%get_value() |
| end function |
| |
| integer function pointer_value (this) |
| class(vector_iter_t), target :: this |
| class(gfc_cont_elem_t), pointer :: ptr |
| ptr => this%container%vec_elem |
| pointer_value = ptr%get_value() |
| end function |
| |
| subroutine factory (arg) |
| class (vector_iter_t), pointer :: arg |
| allocate (vector_iter_t :: arg) |
| allocate (vector_t :: arg%container) |
| allocate (arg%container%vec_elem) |
| arg%container%vec_elem%value_p = 99 |
| end subroutine |
| end module |
| |
| use types |
| class (vector_iter_t), pointer :: x |
| |
| call factory (x) |
| if (x%get_vector_value() .ne. 99) STOP 1 |
| if (x%get_pointer_value() .ne. 99) STOP 2 |
| end |