An assignment to a whole polymorphic allocatable changes its dynamic type to the type of the right-hand side expression. But when the assignment is under control of a WHERE statement, or a FORALL / DO CONCURRENT with a mask expression, there is no interpretation of the assignment, as the type of a variable must be the same for all of its elements. There is no restriction in the standard against this usage, and no other Fortran compiler complains about it. But it is not possible to implement it in general, and the behavior produced by other compilers is not reasonable, much less worthy of emulating. It's best to simply disallow it with an error message. Fixes https://github.com/llvm/llvm-project/issues/133669, or more accurately, resolves it.
52 lines
1.2 KiB
Fortran
52 lines
1.2 KiB
Fortran
!RUN: %python %S/test_errors.py %s %flang_fc1
|
|
module m
|
|
contains
|
|
subroutine s(x, y, mask)
|
|
class(*), allocatable, intent(in out) :: x(:), y(:)
|
|
logical, intent(in) :: mask(:)
|
|
select type(x)
|
|
type is(integer)
|
|
print *, 'before, x is integer', x
|
|
type is(real)
|
|
print *, 'before, x is real', x
|
|
class default
|
|
print *, 'before, x has some other type'
|
|
end select
|
|
select type(y)
|
|
type is(integer)
|
|
print *, 'y is integer', y
|
|
type is(real)
|
|
print *, 'y is real', y
|
|
end select
|
|
print *, 'mask', mask
|
|
!ERROR: Assignment to whole polymorphic allocatable 'x' may not be nested in a WHERE statement or construct
|
|
where(mask) x = y
|
|
select type(x)
|
|
type is(integer)
|
|
print *, 'after, x is integer', x
|
|
type is(real)
|
|
print *, 'after, x is real', x
|
|
class default
|
|
print *, 'before, x has some other type'
|
|
end select
|
|
print *
|
|
end
|
|
end
|
|
|
|
program main
|
|
use m
|
|
class(*), allocatable :: x(:), y(:)
|
|
x = [1, 2]
|
|
y = [3., 4.]
|
|
call s(x, y, [.false., .false.])
|
|
x = [1, 2]
|
|
y = [3., 4.]
|
|
call s(x, y, [.false., .true.])
|
|
x = [1, 2]
|
|
y = [3., 4.]
|
|
call s(x, y, [.true., .false.])
|
|
x = [1, 2]
|
|
y = [3., 4.]
|
|
call s(x, y, [.true., .true.])
|
|
end program main
|