Dear Great Intel Fortran developers Team,
as always, thank you very much for your great work.
I have found a different behavior between the Intel Fortran Compiler (v15.0.3) and GNU gfortran (gcc v5.2) when compiling a "possible" wrong (non standard conforming) code. The most simple (not) working example that I can provide is the following:
module adt_foo_class implicit none private type, abstract, public :: adt_foo private contains private procedure(sym_operator), pass(lhs), deferred :: foo_multiply_foo procedure(assignment), pass(lhs), deferred :: assign_foo generic, public :: operator(*) => foo_multiply_foo generic, public :: assignment(=) => assign_foo endtype adt_foo abstract interface function sym_operator(lhs, rhs) result(operator_result) import :: adt_foo class(adt_foo), intent(IN) :: lhs class(adt_foo), intent(IN) :: rhs class(adt_foo), allocatable :: operator_result endfunction sym_operator subroutine assignment(lhs, rhs) import :: adt_foo class(adt_foo), intent(INOUT) :: lhs class(adt_foo), intent(IN) :: rhs endsubroutine assignment endinterface endmodule adt_foo_class module foo_class use adt_foo_class, only : adt_foo implicit none private type, extends(adt_foo), public :: foo private integer, public :: a = 0 contains private procedure, pass(lhs) :: foo_multiply_foo procedure, pass(lhs) :: assign_foo endtype foo contains pure function foo_multiply_foo(lhs, rhs) result(opr) class(foo), intent(IN) :: lhs class(adt_foo), intent(IN) :: rhs class(adt_foo), allocatable :: opr allocate(foo :: opr) select type(opr) class is(foo) opr = lhs select type(rhs) class is (foo) opr%a = lhs%a * rhs%a endselect endselect return endfunction foo_multiply_foo pure subroutine assign_foo(lhs, rhs) class(foo), intent(INOUT) :: lhs class(adt_foo), intent(IN) :: rhs select type(rhs) class is (foo) lhs%a = rhs%a endselect return endsubroutine assign_foo endmodule foo_class program foo_adt_test use foo_class, only : foo implicit none type(foo) :: foo1, foo2, foo3 foo1 = foo(2) foo2 = foo(3) foo3 = foo1 * foo2 print "(I2)", foo3%a stop contains endprogram foo_adt_test
There is an abstract type, namely "adt_foo", that has one deferred operator and one defined assignment defined as "impure". There is a concrete extension of the above abstract type, namely "foo", that has the corresponding operator and assignment defined as "pure". Now, I do not know if this "mismatch" is allowed by the standard (2003/2008), anyway this possible wrong code is compiled differently by Intel Fortran with respect the GNU gfortran. As a matter of facts, Intel Fortran (v15.0.3) compiles this code without warnings and the result obtained by the test is the one expected (6). On the contrary, GNU gfortran (v5.2), does not compile the code and provide the following error message:
→ gfortran foo_adt_test.f90 foo_adt_test.f90:52:13: opr = lhs 1 Error: Subroutine call to ‘assignment’ at (1) is not PURE foo_adt_test.f90:74:4: use foo_class, only : foo 1 Fatal Error: Can't open module file ‘foo_class.mod’ for reading at (1): No such file or directory compilation terminated.
I am not sure, but I think that GNU gfortran is right, the code is wrong. Can you give me some insights on this (possible) issue? Is the code wrong, i.e. not standard?
Note that if you modify the example declaring pure the abstract assignment procedure, GNU gfrotran behaves like Intel Compiler.
For your convenience I have created a dedicated Gist here https://gist.github.com/szaghi/f4f521b6130ee911348f#gistcomment-1664759
Thank you very much for any suggestions,
My best regards.