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

Issues discovered when overloading "generic :: operator(-)"

Alberto_F__M_
Beginner
510 Views

Dear Intel Fortran Compiler for Linux and Mac OS X users and developers,

I think that I found a number of issues when overloading "generic :: operator(-)" on a base derived data type -- let's call it A -- and calling the corresponding bindings with instances of a derived data type which extends A, --let's call it B--. The different scenarios tested were gathered in five programs attached to this post: test1.f90, test2.f90, test3.f90, test4.f90, and test5.f90. The outcome was as follows:

- test1.f90 compiles and generates the output that I would expect (OK).

amartin@Aetos:~/pruebas_fortran_03$ ifort test1.f90
amartin@Aetos:~/pruebas_fortran_03$ ./a.out
   2.000000    
   2.000000

- test2.f90 compiles but it DOES NOT provide the output that I would expect (I believe the expected output should be the same as the one provided by test1.f90) (NO-OK).

amartin@Aetos:~/pruebas_fortran_03$ ifort test2.f90
amartin@Aetos:~/pruebas_fortran_03$ ./a.out
 
   2.000000

- test3.f90 compiles but and generates the output that I would expect (OK).

amartin@Aetos:~/pruebas_fortran_03$ ifort test3.f90
amartin@Aetos:~/pruebas_fortran_03$ ./a.out
   1.000000

- test4.f90 DOES NOT compile, and I believe that it should compile (NO-OK).

amartin@Aetos:~/pruebas_fortran_03$ ifort test4.f90
test4.f90(46): error #6355: This binary operation is invalid for this data type.   [B_INSTANCE]
  write(*,*) B_instance-B_instance
-------------^
test4.f90(46): error #6355: This binary operation is invalid for this data type.   [B_INSTANCE]
  write(*,*) B_instance-B_instance
------------------------^
test4.f90(46): error #6549: An arithmetic or LOGICAL type is required in this context.
  write(*,*) B_instance-B_instance
-----------------------^
compilation aborted for test4.f90 (code 1)

- test5.f90 compiles and generates the output that I would expect (OK).

amartin@Aetos:~/pruebas_fortran_03$ ifort test5.f90
amartin@Aetos:~/pruebas_fortran_03$ ./a.out
   1.000000    
   1.000000

If you take a careful look at the code snippets, you may observe that the NO-OK tests are the ones where the "generic :: operator(-)" is overloaded for both the unary and binary minus operator.

Could you please help me and determine whether the codes are standard compliant, and confirm that they should provide the outputs that I except? In case I am correct, is there any compiler-related issue? Can it be work-arounded? Should it be fixed?

I got the same behaviour with both the 15.0.2 and 16.0.0 compiler versions.With the GNU gfortran compiler (5.1.0) all tests compiled and generated the output that I would expect.

Many thanks in advance for your help.

 

 

 

 

 

0 Kudos
2 Replies
FortranFan
Honored Contributor III
510 Views

Alberto F. M. wrote:

Dear Intel Fortran Compiler for Linux and Mac OS X users and developers,

.. Could you please help me and determine whether the codes are standard compliant, and confirm that they should provide the outputs that I except? In case I am correct, is there any compiler-related issue? Can it be work-arounded? Should it be fixed?

..

Your code appears standard-conforming and the underlying issue seems to be in Intel Fortran which, if accepted by the Intel team as such, should get fixed.

You ask, "Can it be work-arounded?"  How about going with a lettered defined operation until the compiler gets fixed?

module A_class

   implicit none

   type :: A
   contains
      procedure :: minus_A
      procedure :: sub_A
      generic :: operator(-) => minus_A
      generic :: operator(.minus.) => sub_A
   end type A

contains

   function sub_A(op1,op2) result(res)
      implicit none
      class(A), intent(in) :: op1, op2
      real :: res
      res=1.0
   end function sub_A

   function minus_A(op) result(res)
      implicit none
      class(A), intent(in) :: op
      real :: res
      res=2.0
   end function minus_A

end module A_class

module B_class

   use A_class, only : A

   implicit none

   type, extends(A) :: B
   end type B

end module B_class
program example_program

   use A_class, only : A
   use B_class, only : B

   implicit none

   type(B), target :: B_instance
   class(A), pointer :: A_pointer

   A_pointer => B_instance

   write(*,*) -B_instance
   write(*,*) -A_pointer

   stop

end program example_program
 2.000000
 2.000000
Press any key to continue . . .

 

0 Kudos
Kevin_D_Intel
Employee
510 Views

@Alberto, I will look into your test cases also and reply again after knowing more.

@FortranFan, Appreciate your investigating and for the work around.

0 Kudos
Reply