forked from OSchip/llvm-project
[flang] Fix another bug checking simple contiguity
The test still wasn't correct for structure components. If the last part-ref is a non-array or a single array element, but the whole ArrayRef has non-zero rank, it is not contiguous. Otherwise, if there are subscripts on the last part-ref they can be checked normally. Add some tests for cases that were previously failing, and also for cases with vector subscripts. Original-commit: flang-compiler/f18@aa0a088732 Reviewed-on: https://github.com/flang-compiler/f18/pull/961
This commit is contained in:
parent
6d92012d23
commit
f1b61dbd5e
|
@ -277,11 +277,18 @@ public:
|
|||
}
|
||||
|
||||
Result operator()(const ArrayRef &x) const {
|
||||
return (x.base().IsSymbol() || x.base().Rank() == 0) &&
|
||||
CheckSubscripts(x.subscript()) && (*this)(x.base());
|
||||
const auto &symbol{x.GetLastSymbol()};
|
||||
if (!(*this)(symbol)) {
|
||||
return false;
|
||||
} else if (auto rank{CheckSubscripts(x.subscript())}) {
|
||||
// a(:)%b(1,1) is not contiguous; a(1)%b(:,:) is
|
||||
return *rank > 0 || x.Rank() == 0;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Result operator()(const CoarrayRef &x) const {
|
||||
return CheckSubscripts(x.subscript());
|
||||
return CheckSubscripts(x.subscript()).has_value();
|
||||
}
|
||||
Result operator()(const Component &x) const {
|
||||
return x.base().Rank() == 0 && (*this)(x.GetLastSymbol());
|
||||
|
@ -304,24 +311,30 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
static bool CheckSubscripts(const std::vector<Subscript> &subscript) {
|
||||
// If the subscripts can possibly be on a simply-contiguous array reference,
|
||||
// return the rank.
|
||||
static std::optional<int> CheckSubscripts(
|
||||
const std::vector<Subscript> &subscript) {
|
||||
bool anyTriplet{false};
|
||||
int rank{0};
|
||||
for (auto j{subscript.size()}; j-- > 0;) {
|
||||
if (const auto *triplet{std::get_if<Triplet>(&subscript[j].u)}) {
|
||||
if (!triplet->IsStrideOne()) {
|
||||
return false;
|
||||
return std::nullopt;
|
||||
} else if (anyTriplet) {
|
||||
if (triplet->lower() || triplet->upper()) {
|
||||
return false; // all triplets before the last one must be just ":"
|
||||
// all triplets before the last one must be just ":"
|
||||
return std::nullopt;
|
||||
}
|
||||
} else {
|
||||
anyTriplet = true;
|
||||
}
|
||||
++rank;
|
||||
} else if (anyTriplet || subscript[j].Rank() > 0) {
|
||||
return false;
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return rank;
|
||||
}
|
||||
|
||||
const IntrinsicProcTable &table_;
|
||||
|
|
|
@ -142,12 +142,22 @@ contains
|
|||
end type
|
||||
type(t), target :: x
|
||||
type(t), target :: y(10,10)
|
||||
integer :: v(10)
|
||||
p(1:16) => x%a
|
||||
p(1:8) => x%a(:,3:4)
|
||||
p(1:1) => x%b ! We treat scalars as simply contiguous
|
||||
p(1:1) => x%a(1,1)
|
||||
p(1:1) => y(1,1)%a(1,1)
|
||||
p(1:1) => y(:,1)%a(1,1) ! Rank 1 RHS
|
||||
!ERROR: Pointer bounds remapping target must have rank 1 or be simply contiguous
|
||||
p(1:4) => x%a(::2,::2)
|
||||
!ERROR: Pointer bounds remapping target must have rank 1 or be simply contiguous
|
||||
p(1:100) => y(:,:)%b
|
||||
!ERROR: Pointer bounds remapping target must have rank 1 or be simply contiguous
|
||||
p(1:100) => y(:,:)%a(1,1)
|
||||
!ERROR: Pointer bounds remapping target must have rank 1 or be simply contiguous
|
||||
!ERROR: An array section with a vector subscript may not be a pointer target
|
||||
p(1:4) => x%a(:,v)
|
||||
end
|
||||
|
||||
subroutine s11
|
||||
|
@ -155,8 +165,31 @@ contains
|
|||
complex, pointer :: p(:)
|
||||
real, pointer :: q(:)
|
||||
p(1:100) => x(:,:)
|
||||
q(1:10) => x(1,:)%im
|
||||
!ERROR: Pointer bounds remapping target must have rank 1 or be simply contiguous
|
||||
q(1:100) => x(:,:)%re
|
||||
end
|
||||
|
||||
! Check is_contiguous, which is usually the same as when pointer bounds
|
||||
! remapping is used. If it's not simply contiguous it's not constant so
|
||||
! an error is reported.
|
||||
subroutine s12
|
||||
integer, pointer :: p(:)
|
||||
type :: t
|
||||
integer :: a(4, 4)
|
||||
integer :: b
|
||||
end type
|
||||
type(t), target :: x
|
||||
type(t), target :: y(10,10)
|
||||
integer :: v(10)
|
||||
logical, parameter :: l1 = is_contiguous(x%a(:,:))
|
||||
logical, parameter :: l2 = is_contiguous(y(1,1)%a(1,1))
|
||||
!ERROR: Must be a constant value
|
||||
logical, parameter :: l3 = is_contiguous(y(:,1)%a(1,1))
|
||||
!ERROR: Must be a constant value
|
||||
logical, parameter :: l4 = is_contiguous(x%a(:,v))
|
||||
!ERROR: Must be a constant value
|
||||
logical, parameter :: l5 = is_contiguous(y(v,1)%a(1,1))
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue