[flang-commits] [flang] [flang] Do not error when `NAMELIST` found within interface body (PR #175079)

Miguel Saldivar via flang-commits flang-commits at lists.llvm.org
Thu Jan 8 14:26:36 PST 2026


https://github.com/Saldivarcher created https://github.com/llvm/llvm-project/pull/175079

Flang would error on code like:
```
Program test
  real, allocatable :: array(:,:)
  real, pointer :: array_ptr(:)
  interface
     subroutine sub1( array, array_ptr  )
       real array(:,:)
       real, pointer :: array_ptr(:)
       namelist /my_namelist / array, array_ptr
     End subroutine sub1
  end interface
End Program test
```
with an error like:
```
error: Semantic errors in simple.f90
./simple.f90:8:32: error: Internal: no symbol found for 'array'
         namelist /my_namelist / array, array_ptr
                                 ^^^^^
./simple.f90:8:39: error: Internal: no symbol found for 'array_ptr'
         namelist /my_namelist / array, array_ptr
                                        ^^^^^^^^^
```

What this fix does is suppress an error if a `NAMELIST` is found within an interface.

>From e6410f8790dfcea457ec789cfc25fb60206e6bc6 Mon Sep 17 00:00:00 2001
From: Miguel Saldivar <miguel.saldivar at hpe.com>
Date: Thu, 8 Jan 2026 16:04:43 -0600
Subject: [PATCH] [flang] Do not error when `NAMELIST` found within interface
 body

Flang would error on code like:
```
Program test
  real, allocatable :: array(:,:)
  real, pointer :: array_ptr(:)
  interface
     subroutine sub1( array, array_ptr  )
       real array(:,:)
       real, pointer :: array_ptr(:)
       namelist /my_namelist / array, array_ptr
     End subroutine sub1
  end interface
End Program test
```
with an error like:
```
error: Semantic errors in simple.f90
./simple.f90:8:32: error: Internal: no symbol found for 'array'
         namelist /my_namelist / array, array_ptr
                                 ^^^^^
./simple.f90:8:39: error: Internal: no symbol found for 'array_ptr'
         namelist /my_namelist / array, array_ptr
                                        ^^^^^^^^^
```

What this fix does is suppress an error if a `NAMELIST` is found within
an interface.
---
 flang/lib/Semantics/rewrite-parse-tree.cpp  | 51 +++++++++++++++++++++
 flang/test/Semantics/namelist-interface.f90 | 12 +++++
 2 files changed, 63 insertions(+)
 create mode 100644 flang/test/Semantics/namelist-interface.f90

diff --git a/flang/lib/Semantics/rewrite-parse-tree.cpp b/flang/lib/Semantics/rewrite-parse-tree.cpp
index 60e3e6ab3f5f1..cfdfe7e842db9 100644
--- a/flang/lib/Semantics/rewrite-parse-tree.cpp
+++ b/flang/lib/Semantics/rewrite-parse-tree.cpp
@@ -86,6 +86,9 @@ class RewriteMutator {
   void Post(parser::OmpBlockConstruct &);
   void Post(parser::OpenMPLoopConstruct &);
 
+  bool Pre(parser::InterfaceBody &);
+  void Post(parser::InterfaceBody &);
+
 private:
   void FixMisparsedStmtFuncs(parser::SpecificationPart &, parser::Block &);
   void OpenMPSimdOnly(parser::Block &, bool);
@@ -406,6 +409,54 @@ void RewriteMutator::Post(parser::OpenMPLoopConstruct &ompLoop) {
   this->Pre(ompLoop);
 }
 
+// Scans through `SpecificationPart` declarations to detect presence of
+// `NAMELIST`.
+static bool HasNameList(const parser::SpecificationPart &spec) {
+  const auto &decls = std::get<std::list<parser::DeclarationConstruct>>(spec.t);
+  for (const auto &decl : decls) {
+    if (const auto *specConstruct =
+            std::get_if<parser::SpecificationConstruct>(&decl.u)) {
+      if (const auto *ossStmt =
+              std::get_if<parser::Statement<parser::OtherSpecificationStmt>>(
+                  &specConstruct->u)) {
+        const auto &oss = ossStmt->statement;
+        if (std::get_if<common::Indirection<parser::NamelistStmt>>(&oss.u)) {
+          return true;
+        }
+      }
+    }
+  }
+
+  return false;
+}
+
+// Suppress `errorOnUnresolvedName_` if a `NAMELIST` is present within an
+// interface body, dummy names should get resolved later by semantics.
+bool RewriteMutator::Pre(parser::InterfaceBody &interfaceBody) {
+  const auto &u = interfaceBody.u;
+  const parser::SpecificationPart *spec = nullptr;
+  if (const auto *func = std::get_if<parser::InterfaceBody::Function>(&u)) {
+    spec = &std::get<common::Indirection<parser::SpecificationPart>>(func->t)
+                .value();
+  } else if (const auto *subroutine =
+                 std::get_if<parser::InterfaceBody::Subroutine>(&u)) {
+    spec =
+        &std::get<common::Indirection<parser::SpecificationPart>>(subroutine->t)
+             .value();
+  }
+
+  if (spec && HasNameList(*spec)) {
+    errorOnUnresolvedName_ = false;
+  }
+
+  return true;
+}
+
+// Restore `errorOnUnresolvedName_` to original value.
+void RewriteMutator::Post(parser::InterfaceBody &) {
+  errorOnUnresolvedName_ = !context_.AnyFatalError();
+}
+
 bool RewriteMutator::Pre(parser::DoConstruct &doConstruct) {
   if (context_.langOptions().OpenMPSimd) {
     auto &innerBlock = std::get<parser::Block>(doConstruct.t);
diff --git a/flang/test/Semantics/namelist-interface.f90 b/flang/test/Semantics/namelist-interface.f90
new file mode 100644
index 0000000000000..708ef2ab0cd82
--- /dev/null
+++ b/flang/test/Semantics/namelist-interface.f90
@@ -0,0 +1,12 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1
+program test
+  real, allocatable :: array(:,:)
+  real, pointer :: array_ptr(:)
+  interface
+     subroutine sub1(array, array_ptr)
+       real array(:,:)
+       real, pointer :: array_ptr(:)
+       namelist /my_namelist/ array, array_ptr
+     end subroutine sub1
+  end interface
+end program test



More information about the flang-commits mailing list