- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.)
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you! Love these nice reproducers!
I'll check this out.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I filed a bug, CMPLRLLVM-45596. This reproducer gets the same wrong results with ifx.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
With the release of 2024.0, both ifx and ifort are printing the correct answers at runtime.
Please check out the new releases.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The testcase is fixed, indeed!
Thanks!

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page