[flang-commits] [PATCH] D143778: [flang] Fix crash on SELECT RANK

Peter Klausler via Phabricator via flang-commits flang-commits at lists.llvm.org
Fri Feb 10 13:58:26 PST 2023


klausler created this revision.
klausler added a reviewer: vdonaldson.
klausler added a project: Flang.
Herald added subscribers: sunshaoce, jdoerfert.
Herald added a project: All.
klausler requested review of this revision.

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.


https://reviews.llvm.org/D143778

Files:
  flang/include/flang/Evaluate/tools.h
  flang/lib/Evaluate/shape.cpp
  flang/lib/Evaluate/tools.cpp
  flang/lib/Semantics/expression.cpp


Index: flang/lib/Semantics/expression.cpp
===================================================================
--- flang/lib/Semantics/expression.cpp
+++ 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()) {
Index: flang/lib/Evaluate/tools.cpp
===================================================================
--- flang/lib/Evaluate/tools.cpp
+++ 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<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
Index: flang/lib/Evaluate/shape.cpp
===================================================================
--- flang/lib/Evaluate/shape.cpp
+++ 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<semantics::AssocEntityDetails>()}) {
     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<semantics::ObjectEntityDetails>()}) {
     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<semantics::ObjectEntityDetails>()}) {
     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<semantics::ObjectEntityDetails>()}) {
     Shape result;
     int dim{0};
Index: flang/include/flang/Evaluate/tools.h
===================================================================
--- flang/include/flang/Evaluate/tools.h
+++ 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 &);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D143778.496595.patch
Type: text/x-patch
Size: 4052 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/flang-commits/attachments/20230210/9f5bed68/attachment-0001.bin>


More information about the flang-commits mailing list