Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29071 Discussions

[BUG] overriding deferred private procedure of abstract type defined in separate module raises error

SebastianM
Novice
412 Views

I found a strange bug, present in all ifort ifx version I tried (2023.2.0 - 2025.1).

This fails to compile:

module abc
  type, abstract :: abc_example
  contains
    procedure(print_func), deferred, private :: print
    generic :: write => print
  end type abc_example
  ! interface
  abstract interface
    subroutine print_func(this)
      import :: abc_example
      class(abc_example), intent(in) :: this
    end subroutine print_func
  end interface
end module abc

module implement
  use abc, only: abc_example
  type, extends(abc_example), public :: example
  contains
    procedure, private :: print => print_example
  end type example
contains
  subroutine print_example(this)
    class(example), intent(in) :: this
    print*, "WORKS"
  end subroutine print_example
end module implement

program test_abc
  use implement, only: example
  type(example) :: my_example
  call my_example%write()
end program test_abc

with this error:

$ ifx fail_intel.f90 
fail_intel.f90: error #8322: A deferred binding is inherited by non-abstract type; It must be overridden.   [PRINT]
fail_intel.f90(17): error #6136: Derived-type declared must be ABSTRACT   [EXAMPLE]
  type, extends(abc_example), public :: example
----------------------------------------^
compilation aborted for fail_intel.f90 (code 1)

The error can be prevented in two (strange) ways:
1. remove the `private` attribute from the deferred print method.
2. having `abc_example` and `example` in the same module (moving `abc_example` into `implement` works)

0 Kudos
1 Solution
Xiaoping_D_Intel
Employee
82 Views

We can confirm that it isn't a compiler bug. ifx is exhibiting the correct behavior in issuing an error for this. A private component is inaccessible when the parent type is use associated. 


View solution in original post

0 Kudos
4 Replies
Xiaoping_D_Intel
Employee
320 Views

A bug report has been opened for it.


WileyOne
Novice
196 Views

I am (mostly) sure this is not a bug; I've attempted to do this before and - per my reading of the standard - it's not allowed. Private procedures are only accessible (including the ability to override them) within the appropriate scope (that module and its submodules). There is no exception given for deferred procedures. That means that only child classes living in the host module or its submodules can overwrite private deferred procedures. If the child class lives in a separate module, then the deferred procedure must be public. This matches exactly what you're seeing. The relevant sections of the 2018 standard are 14.2.2 and 7.5.5.9.

0 Kudos
Xiaoping_D_Intel
Employee
83 Views

We can confirm that it isn't a compiler bug. ifx is exhibiting the correct behavior in issuing an error for this. A private component is inaccessible when the parent type is use associated. 


0 Kudos
SebastianM
Novice
12 Views

Thank you for the investigation. The original issue was an implementation for an equal comparison method, that was then used for the "==" operator:

procedure(equal_if), private, deferred :: equal
generic, public :: operator(==) => equal

Here it makes totally sense, that the equal is private, since the operator should be used. Problem then is, that an implementation can only be in the same module. So in the end I would say, I dislike this language decision and it may is hard to debug, since the abstract type can be used, but not extended in a foreign module.

0 Kudos
Reply