[flang] Allow compiler directives in the specification part of a module
authorV Donaldson <vdonaldson@nvidia.com>
Wed, 1 Feb 2023 20:52:42 +0000 (12:52 -0800)
committerV Donaldson <vdonaldson@nvidia.com>
Wed, 1 Feb 2023 22:50:38 +0000 (14:50 -0800)
Lowering code currently allows for directives inside a program or
subprogram, or outside any program unit. Directives may also appear
in the specification part of a module, as in:

module mm
  interface
     subroutine ss(aa)
       !dir$ ignore_tkr(tkr) aa
       integer :: aa(*)
     end subroutine ss
  end interface
end module

With some exceptions such as OpenMP directives, most directives are
currently ignored, so this code should generate an "ignoring all compiler
directives" message.

flang/lib/Lower/PFTBuilder.cpp
flang/test/Lower/pre-fir-tree02.f90

index a5f1ed7..b9215f5 100644 (file)
@@ -396,7 +396,7 @@ private:
     assert(!evaluationListStack.empty() && "empty evaluation list stack");
     if (!constructAndDirectiveStack.empty())
       eval.parentConstruct = constructAndDirectiveStack.back();
-    auto &entryPointList = eval.getOwningProcedure()->entryPointList;
+    lower::pft::FunctionLikeUnit *owningProcedure = eval.getOwningProcedure();
     evaluationListStack.back()->emplace_back(std::move(eval));
     lower::pft::Evaluation *p = &evaluationListStack.back()->back();
     if (p->isActionStmt() || p->isConstructStmt() || p->isEndStmt() ||
@@ -408,11 +408,14 @@ private:
         p->printIndex = 1;
       }
       lastLexicalEvaluation = p;
-      for (std::size_t entryIndex = entryPointList.size() - 1;
-           entryIndex && !entryPointList[entryIndex].second->lexicalSuccessor;
-           --entryIndex)
-        // Link to the entry's first executable statement.
-        entryPointList[entryIndex].second->lexicalSuccessor = p;
+      if (owningProcedure) {
+        auto &entryPointList = owningProcedure->entryPointList;
+        for (std::size_t entryIndex = entryPointList.size() - 1;
+             entryIndex && !entryPointList[entryIndex].second->lexicalSuccessor;
+             --entryIndex)
+          // Link to the entry's first executable statement.
+          entryPointList[entryIndex].second->lexicalSuccessor = p;
+      }
     } else if (const auto *entryStmt = p->getIf<parser::EntryStmt>()) {
       const semantics::Symbol *sym =
           std::get<parser::Name>(entryStmt->t).symbol;
@@ -420,7 +423,7 @@ private:
         sym = details->specific();
       assert(sym->has<semantics::SubprogramDetails>() &&
              "entry must be a subprogram");
-      entryPointList.push_back(std::pair{sym, p});
+      owningProcedure->entryPointList.push_back(std::pair{sym, p});
     }
     if (p->label.has_value())
       labelEvaluationMap->try_emplace(*p->label, p);
index 551cd45..f4fa626 100644 (file)
@@ -155,6 +155,13 @@ module test
   !![disable]type, extends(a_type) :: b_type
   !![disable]  integer :: y
   !![disable]end type
+  interface
+     subroutine ss(aa)
+       ! CHECK: CompilerDirective
+       !DIR$ IGNORE_TKR aa
+       integer :: aa
+     end subroutine ss
+  end interface
 contains
   ! CHECK: Function foo
   function foo(x)
@@ -212,7 +219,7 @@ contains
   ! CHECK: Subroutine sub
   subroutine sub(a)
     real(4):: a
-    ! CompilerDirective:
+    ! CHECK: CompilerDirective
     !DIR$ IGNORE_TKR a
   end subroutine