[flang] Retrieve the correct scope when lowering SELECT TYPE
authorValentin Clement <clementval@gmail.com>
Thu, 16 Feb 2023 08:05:12 +0000 (09:05 +0100)
committerValentin Clement <clementval@gmail.com>
Thu, 16 Feb 2023 08:05:35 +0000 (09:05 +0100)
Scope to retrieve the associating entity is needed to map the
symbol to the IR value. The scope can be found with a source
information. For the type case in SELECT TYPE construct, the source
information is on the Statement<TypeCase>. This patch updates
the lowering so the scopes for each type guards is retrieved
before the processing.

Reviewed By: PeteSteinfeld, vdonaldson

Differential Revision: https://reviews.llvm.org/D144133

flang/lib/Lower/Bridge.cpp
flang/test/Lower/select-type.f90

index a87027e..717bdec 100644 (file)
@@ -2179,6 +2179,19 @@ private:
     unsigned typeGuardIdx = 0;
     std::size_t defaultAttrPos = std::numeric_limits<size_t>::max();
     bool hasLocalScope = false;
+    llvm::SmallVector<const Fortran::semantics::Scope *> typeCaseScopes;
+
+    const auto &typeCaseList =
+        std::get<std::list<Fortran::parser::SelectTypeConstruct::TypeCase>>(
+            selectTypeConstruct.t);
+    for (const auto &typeCase : typeCaseList) {
+      const auto &stmt =
+          std::get<Fortran::parser::Statement<Fortran::parser::TypeGuardStmt>>(
+              typeCase.t);
+      const Fortran::semantics::Scope &scope =
+          bridge.getSemanticsContext().FindScope(stmt.source);
+      typeCaseScopes.push_back(&scope);
+    }
 
     for (Fortran::lower::pft::Evaluation &eval :
          getEval().getNestedEvaluations()) {
@@ -2275,13 +2288,11 @@ private:
                "TypeGuard attribute missing");
         mlir::Attribute typeGuardAttr = attrList[typeGuardIdx];
         mlir::Block *typeGuardBlock = blockList[typeGuardIdx];
-        const Fortran::semantics::Scope &guardScope =
-            bridge.getSemanticsContext().FindScope(eval.position);
         mlir::OpBuilder::InsertPoint crtInsPt = builder->saveInsertionPoint();
         builder->setInsertionPointToStart(typeGuardBlock);
 
         auto addAssocEntitySymbol = [&](fir::ExtendedValue exv) {
-          for (auto &symbol : guardScope.GetSymbols()) {
+          for (auto &symbol : typeCaseScopes[typeGuardIdx]->GetSymbols()) {
             if (symbol->GetUltimate()
                     .detailsIf<Fortran::semantics::AssocEntityDetails>()) {
               addSymbol(symbol, exv);
index 8467582..b585185 100644 (file)
@@ -756,6 +756,23 @@ contains
 ! CHECK: ^bb6:
 ! CHECK: ^bb7:
 
+  subroutine select_type14(a, b)
+    class(p1) :: a, b
+
+    select type(a)
+      type is (p2)
+        select type (b)
+          type is (p2)
+            print*,a%c,b%C
+        end select
+      class default
+        print*,a%a
+    end select
+  end subroutine
+
+  ! Just makes sure the example can be lowered.
+  ! CHECK-LABEL: func.func @_QMselect_type_lower_testPselect_type14
+   
 end module
 
 program test_select_type