An object is polymorphic when its specific type may vary.
The types a specific value may take, is called class.

It is trivial to copy an object if its type is known:

int x;
int y = x;
Here x is not polymorphic, so y is declared of same type (int) as x.
But if the specific type of x were unknown, then y could not be declared of any specific type.

The task: let a polymorphic object contain an instance of some specific type S derived from a type T.
The type T is known.
The type S is possibly unknown until run time.
The objective is to create an exact copy of such polymorphic object (not to create a reference, nor a pointer to).
Let further the type T have a method overridden by S.
This method is to be called on the copy to demonstrate that the specific type of the copy is indeed S.

 
!-----------------------------------------------------------------------
!Module polymorphic_copy_example_module
!-----------------------------------------------------------------------
module polymorphic_copy_example_module
   implicit none
   private ! all by default
   public :: T,S
 
   type, abstract :: T
   contains
      procedure (T_procedure1), deferred, pass :: identify
      procedure (T_procedure2), deferred, pass :: duplicate
   end type T
 
 
   abstract interface
      subroutine T_procedure1(this)
         import  :: T
         class(T), intent(inout) :: this
      end subroutine T_procedure1
      function T_procedure2(this) result(Tobj)
         import  :: T
         class(T), intent(inout) :: this
         class(T), allocatable :: Tobj
      end function T_procedure2
   end interface
 
   type, extends(T) :: S
   contains
      procedure, pass :: identify
      procedure, pass :: duplicate
   end type S
 
 contains
 
   subroutine  identify(this)
      implicit none
      class(S), intent(inout) :: this
      write(*,*) "S"
   end subroutine identify
 
   function duplicate(this) result(obj)
      class(S), intent(inout) :: this
      class(T), allocatable :: obj
      allocate(obj, source = S())
   end function duplicate
 
end module polymorphic_copy_example_module
 
!-----------------------------------------------------------------------
!Main program test
!-----------------------------------------------------------------------
program    test
   use polymorphic_copy_example_module
   implicit none
 
   class(T), allocatable :: Sobj
   class(T), allocatable :: Sclone
 
   allocate(Sobj, source = S())
   allocate(Sclone, source = Sobj % duplicate())
 
   call Sobj % identify()
   call Sclone % identify()
 
end program test
 