Quantcast
Channel: Intel® Fortran Compiler
Viewing all articles
Browse latest Browse all 3270

Abstract type/concrete extension interfaces mismatch: different behavior between GNU gfortran and Intel Fortran Compiler

$
0
0

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.

 

 

 


Viewing all articles
Browse latest Browse all 3270

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>