[flang] Return true in IsSymplyContiguous for allocatables

The current code was relying on the fact that allocatables are deferred
shape and that isAssumedShape() should therefore return true for them.

This is not true, because the current parsing/semantic analysis always
builds a semantics::ArraySpec for `x(:)` that returns true to both
isDeferredShape()/isAssumedShape(), whether x is allocatable/pointer or
not.

It proved tricky to change this behavior, so this is a simple fix for
IsSymplyContiguous where it currently matters, but we most likely want
to investigate more and fix the isDeferredShape()/isAssumedShape() in
a second time.

Differential Revision: https://reviews.llvm.org/D114599
This commit is contained in:
Jean Perier 2021-11-29 08:27:16 +01:00
parent 4709bacf18
commit 9d1938fd14
2 changed files with 10 additions and 3 deletions

View File

@ -661,10 +661,15 @@ public:
return true;
} else if (semantics::IsPointer(ultimate)) {
return false;
} else if (semantics::IsAllocatable(ultimate)) {
// TODO: this could be merged with the case below if
// details->IsAssumedShape() did not return true for allocatables. Current
// ArraySpec building in semantics does not allow making a difference
// between some_assumed_shape(:) and some_allocatable(:). Both
// isDeferredShape() and isAssumedShape() are true in each case.
return true;
} else if (const auto *details{
ultimate.detailsIf<semantics::ObjectEntityDetails>()}) {
// N.B. ALLOCATABLEs are deferred shape, not assumed, and
// are obviously contiguous.
return !details->IsAssumedShape() && !details->IsAssumedRank();
} else if (auto assoc{Base::operator()(ultimate)}) {
return assoc;

View File

@ -9,9 +9,10 @@ module m
real, pointer, contiguous :: f(:)
f => hosted
end function
subroutine test(arr1, arr2, arr3, mat)
subroutine test(arr1, arr2, arr3, mat, alloc)
real, intent(in) :: arr1(:), arr2(10), mat(10, 10)
real, intent(in), contiguous :: arr3(:)
real, allocatable :: alloc(:)
real :: scalar
logical, parameter :: test_isc01 = is_contiguous(0)
logical, parameter :: test_isc02 = is_contiguous(scalar)
@ -24,5 +25,6 @@ module m
logical, parameter :: test_isc09 = is_contiguous(arr2(1:10:1))
logical, parameter :: test_isc10 = is_contiguous(arr3)
logical, parameter :: test_isc11 = is_contiguous(f())
logical, parameter :: test_isc12 = is_contiguous(alloc)
end subroutine
end module