[flang] Address TODO: define IsAssumedRank predicate, use it
Original-commit: flang-compiler/f18@f75c3e0ccfc763644afc3b0fe37861e3a5adcdd9
Reviewed-on: https://github.com/flang-compiler/f18/pull/225
Tree-same-pre-rewrite: false
diff --git a/flang/lib/evaluate/call.h b/flang/lib/evaluate/call.h
index 2ac4cd7..203781e 100644
--- a/flang/lib/evaluate/call.h
+++ b/flang/lib/evaluate/call.h
@@ -41,7 +41,6 @@
std::optional<int> VectorSize() const;
std::optional<parser::CharBlock> keyword;
- bool isAssumedRank{false}; // TODO: make into a function of the value
bool isAlternateReturn{false}; // when true, "value" is a label number
// TODO: Mark legacy %VAL and %REF arguments
diff --git a/flang/lib/evaluate/intrinsics.cc b/flang/lib/evaluate/intrinsics.cc
index 872b46f..8f133f3 100644
--- a/flang/lib/evaluate/intrinsics.cc
+++ b/flang/lib/evaluate/intrinsics.cc
@@ -933,9 +933,9 @@
for (std::size_t j{0}; j < dummies; ++j) {
const IntrinsicDummyArgument &d{dummy[std::min(j, dummyArgPatterns - 1)]};
if (const ActualArgument * arg{actualForDummy[j]}) {
- if (arg->isAssumedRank && d.rank != Rank::anyOrAssumedRank) {
- messages.Say(
- "assumed-rank array cannot be used for '%s=' argument"_err_en_US,
+ if (IsAssumedRank(*arg->value) && d.rank != Rank::anyOrAssumedRank) {
+ messages.Say("assumed-rank array cannot be forwarded to "
+ "'%s=' argument"_err_en_US,
d.keyword);
return std::nullopt;
}
diff --git a/flang/lib/evaluate/tools.h b/flang/lib/evaluate/tools.h
index 7b8608d..37ac767 100644
--- a/flang/lib/evaluate/tools.h
+++ b/flang/lib/evaluate/tools.h
@@ -84,6 +84,23 @@
return std::visit([](const auto &x) { return IsConstant(x); }, expr.u);
}
+// Predicate: true when an expression is assumed-rank
+template<typename A> bool IsAssumedRank(const A &) { return false; }
+template<typename A> bool IsAssumedRank(const Designator<A> &designator) {
+ if (const auto *symbolPtr{
+ std::get_if<const semantics::Symbol *>(&designator.u)}) {
+ if (const auto *details{
+ (*symbolPtr)
+ ->template detailsIf<semantics::ObjectEntityDetails>()}) {
+ return details->IsAssumedRank();
+ }
+ }
+ return false;
+}
+template<typename A> bool IsAssumedRank(const Expr<A> &expr) {
+ return std::visit([](const auto &x) { return IsAssumedRank(x); }, expr.u);
+}
+
// When an expression is a constant integer, extract its value.
template<typename A> std::optional<std::int64_t> ToInt64(const A &) {
return std::nullopt;
diff --git a/flang/lib/semantics/expression.cc b/flang/lib/semantics/expression.cc
index 18fe7d9..9770109 100644
--- a/flang/lib/semantics/expression.cc
+++ b/flang/lib/semantics/expression.cc
@@ -718,7 +718,7 @@
symbol.detailsIf<semantics::ObjectEntityDetails>()}) {
// C928 & C1002
if (Triplet * last{std::get_if<Triplet>(&ref.subscript.back().u)}) {
- if (!last->upper().has_value() && details->isAssumedSize()) {
+ if (!last->upper().has_value() && details->IsAssumedSize()) {
Say("assumed-size array '%s' must have explicit final subscript upper bound value"_err_en_US,
symbol.name().ToString().data());
}
diff --git a/flang/lib/semantics/symbol.h b/flang/lib/semantics/symbol.h
index c981c84..c35a264 100644
--- a/flang/lib/semantics/symbol.h
+++ b/flang/lib/semantics/symbol.h
@@ -124,10 +124,14 @@
void set_shape(const ArraySpec &shape);
bool isDummy() const { return isDummy_; }
bool isArray() const { return !shape_.empty(); }
- bool isAssumedSize() const {
+ bool IsAssumedSize() const {
return isDummy() && isArray() && shape_.back().ubound().isAssumed() &&
!shape_.back().lbound().isAssumed();
}
+ bool IsAssumedRank() const {
+ return isDummy() && isArray() && shape_.back().ubound().isAssumed() &&
+ shape_.back().lbound().isAssumed();
+ }
private:
bool isDummy_;