aboutsummaryrefslogtreecommitdiff
path: root/flang/lib/Semantics/pointer-assignment.cpp
diff options
context:
space:
mode:
authorNAKAMURA Takumi <geek4civic@gmail.com>2025-01-09 17:50:40 +0900
committerNAKAMURA Takumi <geek4civic@gmail.com>2025-01-09 17:50:40 +0900
commitfea7da1b00cc97d742faede2df96c7d327950f49 (patch)
tree4de1d6b4ddc69f4f32daabb11ad5c71ab0cf895e /flang/lib/Semantics/pointer-assignment.cpp
parent9b99dde0d47102625d93c5d1cbbc04951025a6c9 (diff)
parent0aa930a41f2d1ebf1fa90ec42da8f96d15a4dcbb (diff)
downloadllvm-users/chapuni/cov/single/nextcount.zip
llvm-users/chapuni/cov/single/nextcount.tar.gz
llvm-users/chapuni/cov/single/nextcount.tar.bz2
Merge branch 'users/chapuni/cov/single/nextcount-base' into users/chapuni/cov/single/nextcountusers/chapuni/cov/single/nextcount
Diffstat (limited to 'flang/lib/Semantics/pointer-assignment.cpp')
-rw-r--r--flang/lib/Semantics/pointer-assignment.cpp55
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)...)};