diff options
author | NAKAMURA Takumi <geek4civic@gmail.com> | 2025-01-09 18:49:54 +0900 |
---|---|---|
committer | NAKAMURA Takumi <geek4civic@gmail.com> | 2025-01-09 18:49:54 +0900 |
commit | e2810c9a248f4c7fbfae84bb32b6f7e01027458b (patch) | |
tree | ae0b02a8491b969a1cee94ea16ffe42c559143c5 /flang/lib/Semantics/pointer-assignment.cpp | |
parent | fa04eb4af95c1ca7377279728cb004bcd2324d01 (diff) | |
parent | bdcf47e4bcb92889665825654bb80a8bbe30379e (diff) | |
download | llvm-users/chapuni/cov/single/switch.zip llvm-users/chapuni/cov/single/switch.tar.gz llvm-users/chapuni/cov/single/switch.tar.bz2 |
Merge branch 'users/chapuni/cov/single/base' into users/chapuni/cov/single/switchusers/chapuni/cov/single/switch
Diffstat (limited to 'flang/lib/Semantics/pointer-assignment.cpp')
-rw-r--r-- | flang/lib/Semantics/pointer-assignment.cpp | 55 |
1 files changed, 35 insertions, 20 deletions
diff --git a/flang/lib/Semantics/pointer-assignment.cpp b/flang/lib/Semantics/pointer-assignment.cpp index 2450ce3..7f4548c 100644 --- a/flang/lib/Semantics/pointer-assignment.cpp +++ b/flang/lib/Semantics/pointer-assignment.cpp @@ -76,6 +76,7 @@ private: const Procedure * = nullptr, const evaluate::SpecificIntrinsic *specific = nullptr); bool LhsOkForUnlimitedPoly() const; + std::optional<MessageFormattedText> CheckRanks(const TypeAndShape &rhs) const; template <typename... A> parser::Message *Say(A &&...); template <typename FeatureOrUsageWarning, typename... A> parser::Message *Warn(FeatureOrUsageWarning, A &&...); @@ -278,10 +279,19 @@ bool PointerAssignmentChecker::Check(const evaluate::FunctionRef<T> &f) { } else if (lhsType_) { const auto *frTypeAndShape{funcResult->GetTypeAndShape()}; CHECK(frTypeAndShape); - if (!lhsType_->IsCompatibleWith(foldingContext_.messages(), *frTypeAndShape, - "pointer", "function result", - /*omitShapeConformanceCheck=*/isBoundsRemapping_ || isAssumedRank_, - evaluate::CheckConformanceFlags::BothDeferredShape)) { + if (frTypeAndShape->type().IsUnlimitedPolymorphic() && + LhsOkForUnlimitedPoly()) { + // Special case exception to type checking (F'2023 C1017); + // still check rank compatibility. + if (auto msg{CheckRanks(*frTypeAndShape)}) { + Say(*msg); + return false; + } + } else if (!lhsType_->IsCompatibleWith(foldingContext_.messages(), + *frTypeAndShape, "pointer", "function result", + /*omitShapeConformanceCheck=*/isBoundsRemapping_ || + isAssumedRank_, + evaluate::CheckConformanceFlags::BothDeferredShape)) { return false; // IsCompatibleWith() emitted message } } @@ -324,27 +334,17 @@ bool PointerAssignmentChecker::Check(const evaluate::Designator<T> &d) { msg = "Pointer must be VOLATILE when target is a" " VOLATILE coarray"_err_en_US; } + } else if (auto m{CheckRanks(*rhsType)}) { + msg = std::move(*m); } else if (rhsType->type().IsUnlimitedPolymorphic()) { if (!LhsOkForUnlimitedPoly()) { msg = "Pointer type must be unlimited polymorphic or non-extensible" " derived type when target is unlimited polymorphic"_err_en_US; } - } else { - if (!lhsType_->type().IsTkLenCompatibleWith(rhsType->type())) { - msg = MessageFormattedText{ - "Target type %s is not compatible with pointer type %s"_err_en_US, - rhsType->type().AsFortran(), lhsType_->type().AsFortran()}; - - } else if (!isBoundsRemapping_ && - !lhsType_->attrs().test(TypeAndShape::Attr::AssumedRank)) { - int lhsRank{lhsType_->Rank()}; - int rhsRank{rhsType->Rank()}; - if (lhsRank != rhsRank) { - msg = MessageFormattedText{ - "Pointer has rank %d but target has rank %d"_err_en_US, lhsRank, - rhsRank}; - } - } + } else if (!lhsType_->type().IsTkLenCompatibleWith(rhsType->type())) { + msg = MessageFormattedText{ + "Target type %s is not compatible with pointer type %s"_err_en_US, + rhsType->type().AsFortran(), lhsType_->type().AsFortran()}; } } if (msg) { @@ -434,6 +434,21 @@ bool PointerAssignmentChecker::LhsOkForUnlimitedPoly() const { } } +std::optional<MessageFormattedText> PointerAssignmentChecker::CheckRanks( + const TypeAndShape &rhs) const { + if (!isBoundsRemapping_ && + !lhsType_->attrs().test(TypeAndShape::Attr::AssumedRank)) { + int lhsRank{lhsType_->Rank()}; + int rhsRank{rhs.Rank()}; + if (lhsRank != rhsRank) { + return MessageFormattedText{ + "Pointer has rank %d but target has rank %d"_err_en_US, lhsRank, + rhsRank}; + } + } + return std::nullopt; +} + template <typename... A> parser::Message *PointerAssignmentChecker::Say(A &&...x) { auto *msg{foldingContext_.messages().Say(std::forward<A>(x)...)}; |