[flang-commits] [PATCH] D159035: [flang] Accept FINAL forward reference to separate module procedure

Peter Klausler via Phabricator via flang-commits flang-commits at lists.llvm.org
Mon Aug 28 16:30:07 PDT 2023


klausler created this revision.
klausler added a reviewer: clementval.
klausler added a project: Flang.
Herald added a subscriber: jdoerfert.
Herald added a reviewer: sscalpone.
Herald added a project: All.
klausler requested review of this revision.

When one of a derived type's FINAL procedures is in a submodule,
its separate module procedure interface must necessarily be a
forward reference from the FINAL statement, as its interface
could not appear before the definition of the type.  The implementation
of FINAL procedure name resolution doesn't work for forward references;
replace it.


https://reviews.llvm.org/D159035

Files:
  flang/lib/Semantics/resolve-names.cpp
  flang/test/Semantics/symbol30.f90


Index: flang/test/Semantics/symbol30.f90
===================================================================
--- /dev/null
+++ flang/test/Semantics/symbol30.f90
@@ -0,0 +1,19 @@
+! RUN: %python %S/test_symbols.py %s %flang_fc1
+!DEF: /m Module
+module m
+ !DEF: /m/t PUBLIC DerivedType
+ type :: t
+ contains
+  !DEF: /m/forwardreferenced ELEMENTAL, IMPURE, MODULE, PUBLIC (Subroutine) Subprogram
+  final :: forwardreferenced
+ end type
+ interface
+  !REF: /m/forwardreferenced
+  !DEF: /m/forwardreferenced/this INTENT(INOUT) ObjectEntity TYPE(t)
+  impure elemental module subroutine forwardreferenced (this)
+   !REF: /m/t
+   !REF: /m/forwardreferenced/this
+   type(t), intent(inout) :: this
+  end subroutine
+ end interface
+end module
Index: flang/lib/Semantics/resolve-names.cpp
===================================================================
--- flang/lib/Semantics/resolve-names.cpp
+++ flang/lib/Semantics/resolve-names.cpp
@@ -991,7 +991,7 @@
   void Post(const parser::TypeBoundProcBinding &) { EndAttrs(); }
   void Post(const parser::TypeBoundProcedureStmt::WithoutInterface &);
   void Post(const parser::TypeBoundProcedureStmt::WithInterface &);
-  void Post(const parser::FinalProcedureStmt &);
+  bool Pre(const parser::FinalProcedureStmt &);
   bool Pre(const parser::TypeBoundGenericStmt &);
   bool Pre(const parser::StructureDef &); // returns false
   bool Pre(const parser::Union::UnionStmt &);
@@ -5603,24 +5603,31 @@
   }
 }
 
-void DeclarationVisitor::Post(const parser::FinalProcedureStmt &x) {
+bool DeclarationVisitor::Pre(const parser::FinalProcedureStmt &x) {
   if (currScope().IsDerivedType() && currScope().symbol()) {
     if (auto *details{currScope().symbol()->detailsIf<DerivedTypeDetails>()}) {
       for (const auto &subrName : x.v) {
-        if (const auto *name{ResolveName(subrName)}) {
-          auto pair{
-              details->finals().emplace(name->source, DEREF(name->symbol))};
-          if (!pair.second) { // C787
-            Say(name->source,
-                "FINAL subroutine '%s' already appeared in this derived type"_err_en_US,
-                name->source)
-                .Attach(pair.first->first,
-                    "earlier appearance of this FINAL subroutine"_en_US);
-          }
+        Symbol *symbol{FindSymbol(subrName)};
+        if (!symbol) {
+          // FINAL procedures must be module subroutines
+          symbol = &MakeSymbol(
+              currScope().parent(), subrName.source, Attrs{Attr::MODULE});
+          Resolve(subrName, symbol);
+          symbol->set_details(ProcEntityDetails{});
+          symbol->set(Symbol::Flag::Subroutine);
+        }
+        if (auto pair{details->finals().emplace(subrName.source, *symbol)};
+            !pair.second) { // C787
+          Say(subrName.source,
+              "FINAL subroutine '%s' already appeared in this derived type"_err_en_US,
+              subrName.source)
+              .Attach(pair.first->first,
+                  "earlier appearance of this FINAL subroutine"_en_US);
         }
       }
     }
   }
+  return false;
 }
 
 bool DeclarationVisitor::Pre(const parser::TypeBoundGenericStmt &x) {
@@ -7254,7 +7261,7 @@
     Say(name, "No explicit type declared for '%s'"_err_en_US);
     return nullptr;
   }
-  // Create the symbol then ensure it is accessible
+  // Create the symbol, then ensure that it is accessible
   if (checkIndexUseInOwnBounds_ && *checkIndexUseInOwnBounds_ == name.source) {
     Say(name,
         "Implied DO index '%s' uses itself in its own bounds expressions"_err_en_US,


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D159035.554097.patch
Type: text/x-patch
Size: 3566 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/flang-commits/attachments/20230828/48bcd521/attachment-0001.bin>


More information about the flang-commits mailing list