diff --git a/flang/include/flang/Evaluate/tools.h b/flang/include/flang/Evaluate/tools.h --- a/flang/include/flang/Evaluate/tools.h +++ b/flang/include/flang/Evaluate/tools.h @@ -1218,8 +1218,10 @@ // 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 --- a/flang/lib/Evaluate/shape.cpp +++ b/flang/lib/Evaluate/shape.cpp @@ -462,7 +462,7 @@ 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()}) { if (assoc->rank()) { // SELECT RANK case if (semantics::IsDescriptor(symbol) && dimension < *assoc->rank()) { @@ -559,7 +559,8 @@ } 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()}) { int rank{details->shape().Rank()}; if (dimension < rank) { @@ -608,7 +609,8 @@ 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()}) { int rank{details->shape().Rank()}; if (dimension < rank) { @@ -642,7 +644,8 @@ } 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()}) { Shape result; int dim{0}; diff --git a/flang/lib/Evaluate/tools.cpp b/flang/lib/Evaluate/tools.cpp --- a/flang/lib/Evaluate/tools.cpp +++ b/flang/lib/Evaluate/tools.cpp @@ -1212,6 +1212,18 @@ return symbol; } +const Symbol &ResolveAssociationsExceptSelectRank(const Symbol &original) { + const Symbol &symbol{original.GetUltimate()}; + if (const auto *details{symbol.detailsIf()}) { + 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 --- a/flang/lib/Semantics/expression.cpp +++ b/flang/lib/Semantics/expression.cpp @@ -312,7 +312,9 @@ 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()) {