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

Wrong code (missing temporary) passing array section to explicit size dummy

Harald1
New Contributor II
796 Views

Hello,

the following code prints wrong results in the called subroutine:

module m
  implicit none
contains
  subroutine s(a, n)
    integer,  intent(in) :: n
    class(*), intent(in) :: a(n)

    select type(a)
    type is(integer)
       print *,'a is integer, a=', a
    class default
       print *,'a is unsupported type'
       stop 1
    end select
  end
end

program p
  use m
  implicit none
  integer :: b(2,2) = reshape([21, 22, 23, 24], [2,2])

  print *,b
  call s (b,4) ! OK
  print *
  print *,b(:,1::2)
  call s (b(:,1::2),2) ! OK
  print *
  print *,b(1::2,:)
  call s (b(1::2,:),2) ! bad
  print *
  print *,b(2::2,:)
  call s (b(2::2,:),2) ! bad
end

I get with current ifort:

          21          22          23          24
 a is integer, a=          21          22          23          24
 
          21          22
 a is integer, a=          21          22
 
          21          23
 a is integer, a=          21          22
 
          22          24
 a is integer, a=          22          23

So while the first two cases are ok, the last two are not.  Maybe there is no temporary generated for the passed array section to the explicit size dummy, and the actual stride of dimension 1 is not unity.

Thanks,

Harald

 

0 Kudos
1 Solution
Steve_Lionel
Black Belt
654 Views

I'm afraid that I'm on Harald's side here - there is no requirement that the dummy argument be assumed-shape. Sequence association does apply. 

F2018 15.5.2.4

p18 Except when a procedure reference is elemental (15.8), each element of an array actual argument or of a sequence in a sequence association (15.5.2.11) is associated with the element of the dummy array that has the same position in array element order (9.5.3.2).

 

The compiler would have to do copy-in (and copy-out if not INTENT(IN) or a vector subscript.)

View solution in original post

0 Kudos
11 Replies
Barbara_P_Intel
Moderator
752 Views

Thank you! Love these nice reproducers!

I'll check this out.



0 Kudos
Barbara_P_Intel
Moderator
719 Views

I filed a bug, CMPLRLLVM-45596. This reproducer gets the same wrong results with ifx.



0 Kudos
Barbara_P_Intel
Moderator
710 Views

UPDATE... the compiler should actually print an error message.

Intel's resident Fortran standards guru told me:

The problem with the test case is that they are passing a two dimensional array section to a one dimensional explicit shape array. This is wrong because 1) passing an array section requires the dummy argument be assumed shape or deferred shape (bounds are declared with colons), and 2) because they are passing a two dimensional array to a one dimensional array and the interface is explicit.

If at line 6, the dimensions of a are declared as “a(:, :)”, it compiles fine an produces the output.


0 Kudos
Harald1
New Contributor II
699 Views

Would the resident Fortran standard guru please explain this?

For dummy arguments of intrisinc types, this works by F2018: 15.5.2.11 Sequence association.  I do not see a reason for this to not apply here, so any helpful pointer is appreciated.

 

0 Kudos
Harald1
New Contributor II
691 Views

Here's an extended version that allows comparison of intrinsic type dummy and class(*) dummy:

 

module m
  implicit none
contains
  subroutine s(a, n)
    integer,  intent(in) :: n
    class(*), intent(in) :: a(n)

    select type(a)
    type is(integer)
       print *,'a is integer, a=', a
    class default
       print *,'a is unsupported type'
       stop 1
    end select
  end
  subroutine t(a, n)
    integer, intent(in) :: n
    integer, intent(in) :: a(n)
    print *,'subroutine t: a=', a
  end
end

program p
  use m
  implicit none
  integer :: b(2,2) = reshape([21, 22, 23, 24], [2,2])

  print *,b
  call s (b,4) ! OK
  call t (b,4) ! OK
  print *
  print *,b(:,1::2)
  call s (b(:,1::2),2) ! OK
  call t (b(:,1::2),2) ! OK
  print *
  print *,b(1::2,:)
  call s (b(1::2,:),2) ! bad
  call t (b(1::2,:),2) ! OK
  print *
  print *,b(2::2,:)
  call s (b(2::2,:),2) ! bad
  call t (b(2::2,:),2) ! OK
  print *
  print *, "With an explicit temporary:"
  call s ((b(2::2,:)),2) ! this is now OK!
  call t ((b(2::2,:)),2) ! also OK
end

 

So for the subroutine t with a dummy with explicit-shape array of type integer I get what I expect.  With class(*) I'd need an explicit temporary.

 

0 Kudos
Steve_Lionel
Black Belt
655 Views

I'm afraid that I'm on Harald's side here - there is no requirement that the dummy argument be assumed-shape. Sequence association does apply. 

F2018 15.5.2.4

p18 Except when a procedure reference is elemental (15.8), each element of an array actual argument or of a sequence in a sequence association (15.5.2.11) is associated with the element of the dummy array that has the same position in array element order (9.5.3.2).

 

The compiler would have to do copy-in (and copy-out if not INTENT(IN) or a vector subscript.)

0 Kudos
Barbara_P_Intel
Moderator
649 Views

After more research and discussion behind the scenes, the Fortran gurus determined that the original reproducer is valid code and Intel Fortran has a bug. Bug is filed as a runtime issue.



0 Kudos
FortranFan
Honored Contributor II
637 Views

@Barbara_P_Intel ,

It is not convincing this is a run-time issue only.  The evidence is this is a combination issue with the compile-time actions toward the handling of unlimited polymorphic type with the explicit shape received argument.  Because if you try with an integer type as opposed to unlimited polymorphic, you will see the program response is as expected by OP:

module m
contains
   subroutine s(a, n)
      integer, intent(in) :: n
      integer, intent(in) :: a(n)
      print *,'a is integer, a=', a
   end
end

You many want to review this with the Intel Fortran team. 

0 Kudos
Barbara_P_Intel
Moderator
629 Views

@FortranFan, when I said "runtime issue" I meant that the compiler need not print an error message since the code is legal Fortran.

The compiler is indeed generating bad code for this case. That's the bug.



0 Kudos
Barbara_P_Intel
Moderator
261 Views

With the release of 2024.0, both ifx and ifort are printing the correct answers at runtime.

Please check out the new releases.


0 Kudos
Harald1
New Contributor II
242 Views

The testcase is fixed, indeed!

Thanks!

 

0 Kudos
Reply