[flang-commits] [flang] aca9016 - [flang] Fix crash on SELECT RANK
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Sun Feb 12 12:16:36 PST 2023
Author: Peter Klausler
Date: 2023-02-12T12:16:28-08:00
New Revision: aca9016bcde040ea03512ee1e23f61f08b3b07b9
URL: https://github.com/llvm/llvm-project/commit/aca9016bcde040ea03512ee1e23f61f08b3b07b9
DIFF: https://github.com/llvm/llvm-project/commit/aca9016bcde040ea03512ee1e23f61f08b3b07b9.diff
LOG: [flang] Fix crash on SELECT RANK
In some circumstances, such as in compile-time array shape analysis,
clients of the utility function ResolveAssociations() don't really
want it to drill all of the way down to an assumed-rank dummy argument.
Add a variation, ResolveAssociationsExceptSelectRank(), that
will return a specific rank case's AssocEntity symbol instead.
This fixes a crash in subscript validation checking that stemmed from
deducing an incorrect number of lower and upper bound expressions
from a specific rank case association entity.
Differential Revision: https://reviews.llvm.org/D143778
Added:
Modified:
flang/include/flang/Evaluate/tools.h
flang/lib/Evaluate/shape.cpp
flang/lib/Evaluate/tools.cpp
flang/lib/Semantics/expression.cpp
Removed:
################################################################################
diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h
index 291557153453b..448909d365940 100644
--- a/flang/include/flang/Evaluate/tools.h
+++ b/flang/include/flang/Evaluate/tools.h
@@ -1218,8 +1218,10 @@ bool IsEventTypeOrLockType(const DerivedTypeSpec *);
// of the construct entity.
// (E.g., for ASSOCIATE(x => y%z), ResolveAssociations(x) returns x,
// while GetAssociationRoot(x) returns y.)
+// ResolveAssociationsExceptSelectRank() stops at a RANK case symbol.
const Symbol &ResolveAssociations(const Symbol &);
const Symbol &GetAssociationRoot(const Symbol &);
+const Symbol &ResolveAssociationsExceptSelectRank(const Symbol &);
const Symbol *FindCommonBlockContaining(const Symbol &);
int CountLenParameters(const DerivedTypeSpec &);
diff --git a/flang/lib/Evaluate/shape.cpp b/flang/lib/Evaluate/shape.cpp
index 661116bd4b210..6f6baaec2b61e 100644
--- a/flang/lib/Evaluate/shape.cpp
+++ b/flang/lib/Evaluate/shape.cpp
@@ -462,7 +462,7 @@ MaybeExtentExpr GetAssociatedExtent(const NamedEntity &base,
MaybeExtentExpr GetExtent(const NamedEntity &base, int dimension) {
CHECK(dimension >= 0);
const Symbol &last{base.GetLastSymbol()};
- const Symbol &symbol{ResolveAssociations(last)};
+ const Symbol &symbol{ResolveAssociationsExceptSelectRank(last)};
if (const auto *assoc{last.detailsIf<semantics::AssocEntityDetails>()}) {
if (assoc->rank()) { // SELECT RANK case
if (semantics::IsDescriptor(symbol) && dimension < *assoc->rank()) {
@@ -559,7 +559,8 @@ MaybeExtentExpr ComputeUpperBound(
}
MaybeExtentExpr GetRawUpperBound(const NamedEntity &base, int dimension) {
- const Symbol &symbol{ResolveAssociations(base.GetLastSymbol())};
+ const Symbol &symbol{
+ ResolveAssociationsExceptSelectRank(base.GetLastSymbol())};
if (const auto *details{symbol.detailsIf<semantics::ObjectEntityDetails>()}) {
int rank{details->shape().Rank()};
if (dimension < rank) {
@@ -608,7 +609,8 @@ static MaybeExtentExpr GetExplicitUBOUND(
static MaybeExtentExpr GetUBOUND(
FoldingContext *context, const NamedEntity &base, int dimension) {
- const Symbol &symbol{ResolveAssociations(base.GetLastSymbol())};
+ const Symbol &symbol{
+ ResolveAssociationsExceptSelectRank(base.GetLastSymbol())};
if (const auto *details{symbol.detailsIf<semantics::ObjectEntityDetails>()}) {
int rank{details->shape().Rank()};
if (dimension < rank) {
@@ -642,7 +644,8 @@ MaybeExtentExpr GetUBOUND(
}
static Shape GetUBOUNDs(FoldingContext *context, const NamedEntity &base) {
- const Symbol &symbol{ResolveAssociations(base.GetLastSymbol())};
+ const Symbol &symbol{
+ ResolveAssociationsExceptSelectRank(base.GetLastSymbol())};
if (const auto *details{symbol.detailsIf<semantics::ObjectEntityDetails>()}) {
Shape result;
int dim{0};
diff --git a/flang/lib/Evaluate/tools.cpp b/flang/lib/Evaluate/tools.cpp
index 840932c0e0dd6..bf530f857b652 100644
--- a/flang/lib/Evaluate/tools.cpp
+++ b/flang/lib/Evaluate/tools.cpp
@@ -1212,6 +1212,18 @@ const Symbol &ResolveAssociations(const Symbol &original) {
return symbol;
}
+const Symbol &ResolveAssociationsExceptSelectRank(const Symbol &original) {
+ const Symbol &symbol{original.GetUltimate()};
+ if (const auto *details{symbol.detailsIf<AssocEntityDetails>()}) {
+ if (!details->rank()) {
+ if (const Symbol * nested{UnwrapWholeSymbolDataRef(details->expr())}) {
+ return ResolveAssociations(*nested);
+ }
+ }
+ }
+ return symbol;
+}
+
// When a construct association maps to a variable, and that variable
// is not an array with a vector-valued subscript, return the base
// Symbol of that variable, else nullptr. Descends into other construct
diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index b61b97a80554b..116aa7f1504e5 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -312,7 +312,9 @@ MaybeExpr ExpressionAnalyzer::ApplySubscripts(
void ExpressionAnalyzer::CheckConstantSubscripts(ArrayRef &ref) {
// Fold subscript expressions and check for an empty triplet.
Shape lb{GetLBOUNDs(foldingContext_, ref.base())};
+ CHECK(lb.size() >= ref.subscript().size());
Shape ub{GetUBOUNDs(foldingContext_, ref.base())};
+ CHECK(ub.size() >= ref.subscript().size());
bool anyPossiblyEmptyDim{false};
int dim{0};
for (Subscript &ss : ref.subscript()) {
More information about the flang-commits
mailing list