[flang-commits] [flang] [Flang][OpenMP] Fix implicit symbol resolution for USE-renamed arrays (PR #189215)

Aditya Trivedi via flang-commits flang-commits at lists.llvm.org
Wed Jun 10 03:20:30 PDT 2026


https://github.com/adit4443ya updated https://github.com/llvm/llvm-project/pull/189215

>From 4b06e5b9d76bdf6acdaa3b163e8cb5ace5d7a27b Mon Sep 17 00:00:00 2001
From: Aditya Trivedi <adit4443ya at gmail.com>
Date: Thu, 4 Jun 2026 19:14:24 +0530
Subject: [PATCH 1/2]    [Flang][OpenMP] Fix USE-renamed array DSA in OpenMP
 regions
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

  When a module array is imported with a local alias via USE renaming
  (e.g. USE mod, ONLY: s_ary => ary), the OpenMP implicit DSA resolution
  in CreateImplicitSymbols was calling GetUltimate() to find the host
  symbol but using that ultimate symbol's name ("ary") to create the
  HostAssoc in the OMP scope. When two modules both exported a symbol
  named "ary" with different ranks, both collapsed to "ary" in the OMP
  scope causing a rank-mismatch semantic error.

  The fix adds a DeclareNewAccessEntity overload that accepts an explicit
  SourceName, and passes symbol->name() (the local alias "s_ary") rather
  than the ultimate symbol's name ("ary"). GetUltimate() is retained as
  the host anchor — using symbol directly caused infinite loops on the
  second OMP walk because name.symbol pointers are updated to HostAssoc
  symbols in the OMP scope after the first walk, creating self-referential
  HostAssoc chains that GetUltimate() cannot escape.

  Fixes #185344
---
 flang/lib/Semantics/resolve-directives.cpp    | 23 ++++++++++---
 .../Semantics/OpenMP/use-rename-array-dsa.f90 | 32 +++++++++++++++++++
 2 files changed, 51 insertions(+), 4 deletions(-)
 create mode 100644 flang/test/Semantics/OpenMP/use-rename-array-dsa.f90

diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 821724fedc7d4..e7ca817a00235 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -169,6 +169,8 @@ template <typename T> class DirectiveAttributeVisitor {
   const parser::DoConstruct *GetDoConstructIf(
       const parser::ExecutionPartConstruct &);
   Symbol *DeclareNewAccessEntity(const Symbol &, Symbol::Flag, Scope &);
+  Symbol *DeclareNewAccessEntity(
+      const SourceName &, const Symbol &, Symbol::Flag, Scope &);
   Symbol *DeclareAccessEntity(const parser::Name &, Symbol::Flag, Scope &);
   Symbol *DeclareAccessEntity(Symbol &, Symbol::Flag, Scope &);
 
@@ -1127,8 +1129,21 @@ const parser::DoConstruct *DirectiveAttributeVisitor<T>::GetDoConstructIf(
 
 template <typename T>
 Symbol *DirectiveAttributeVisitor<T>::DeclareNewAccessEntity(
-    const Symbol &object, Symbol::Flag flag, Scope &scope) {
+    const SourceName &name, const Symbol &object, Symbol::Flag flag,
+    Scope &scope) {
   assert(object.owner() != currScope());
+  auto &symbol{MakeAssocSymbol(name, object, scope)};
+  symbol.set(flag);
+  if (flag == Symbol::Flag::OmpCopyIn) {
+    // The symbol in copyin clause must be threadprivate entity.
+    symbol.set(Symbol::Flag::OmpThreadprivate);
+  }
+  return &symbol;
+}
+
+template <typename T>
+Symbol *DirectiveAttributeVisitor<T>::DeclareNewAccessEntity(
+    const Symbol &object, Symbol::Flag flag, Scope &scope) {
   auto &symbol{MakeAssocSymbol(object.name(), object, scope)};
   symbol.set(flag);
   if (flag == Symbol::Flag::OmpCopyIn) {
@@ -2564,8 +2579,8 @@ void OmpAttributeVisitor::CreateImplicitSymbols(
           lastDeclSymbol ? lastDeclSymbol : &symbol->GetUltimate();
       assert(flags.LeastElement());
       Symbol::Flag flag = *flags.LeastElement();
-      lastDeclSymbol = DeclareNewAccessEntity(
-          *hostSymbol, flag, context_.FindScope(dirContext.directiveSource));
+      lastDeclSymbol = DeclareNewAccessEntity(symbol->name(), *hostSymbol, flag,
+          context_.FindScope(dirContext.directiveSource));
       lastDeclSymbol->flags() |= flags;
       return lastDeclSymbol;
     };
@@ -2573,7 +2588,7 @@ void OmpAttributeVisitor::CreateImplicitSymbols(
       if (lastDeclSymbol) {
         const Symbol *hostSymbol =
             lastDeclSymbol ? lastDeclSymbol : &symbol->GetUltimate();
-        MakeAssocSymbol(symbol->name(), *hostSymbol,
+        MakeAssocSymbol(hostSymbol->name(), *hostSymbol,
             context_.FindScope(dirContext.directiveSource));
       }
     };
diff --git a/flang/test/Semantics/OpenMP/use-rename-array-dsa.f90 b/flang/test/Semantics/OpenMP/use-rename-array-dsa.f90
new file mode 100644
index 0000000000000..865cdff2eeb24
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/use-rename-array-dsa.f90
@@ -0,0 +1,32 @@
+! RUN: %flang_fc1 -fdebug-dump-symbols -fopenmp %s | FileCheck %s
+
+! Verify that a USE-renamed array (s_ary => ary) is correctly associated in an
+! OpenMP region under the alias name, not the original module name.
+! Regression test for https://github.com/llvm/llvm-project/issues/185344
+
+module use_rename_mod1
+  implicit none
+  real(8), allocatable :: ary(:,:,:)
+end module
+
+module use_rename_mod2
+  implicit none
+  real(8), allocatable :: ary(:,:,:,:,:)
+end module
+
+program test
+  use use_rename_mod1, only: s_ary => ary
+  use use_rename_mod2, only: ary
+  implicit none
+  integer(4) :: i
+
+  !$omp parallel do
+    do i = 1, 10
+      s_ary(i,1,1) = ary(i,1,1,1,1)
+    end do
+  !$omp end parallel do
+end program
+! The loop variable is private and predetermined.
+! CHECK: i (OmpPrivate, OmpPreDetermined): HostAssoc
+! The OMP region must create a host-association for s_ary under its alias name.
+! CHECK: s_ary (OmpShared): HostAssoc

>From e56169ca8d39261608da5cc27e4297f07756ff3a Mon Sep 17 00:00:00 2001
From: Aditya Trivedi <adit4443ya at gmail.com>
Date: Wed, 10 Jun 2026 15:46:45 +0530
Subject: [PATCH 2/2] [FLang][OpenMP] Address review feedback

Expand FileCheck patterns to verify scope structure and HostAssoc targets, Remove assert from DeclareNewAccessEntity(SourceName,..), Simplify DeclareNewAccessEntity(Symbol&,...) to delegate to the SourcceName overload instead of duplicating the body,
---
 flang/lib/Semantics/resolve-directives.cpp           | 9 +--------
 flang/test/Semantics/OpenMP/use-rename-array-dsa.f90 | 8 +++++---
 2 files changed, 6 insertions(+), 11 deletions(-)

diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index e7ca817a00235..6ebe093421f4d 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -1131,7 +1131,6 @@ template <typename T>
 Symbol *DirectiveAttributeVisitor<T>::DeclareNewAccessEntity(
     const SourceName &name, const Symbol &object, Symbol::Flag flag,
     Scope &scope) {
-  assert(object.owner() != currScope());
   auto &symbol{MakeAssocSymbol(name, object, scope)};
   symbol.set(flag);
   if (flag == Symbol::Flag::OmpCopyIn) {
@@ -1144,13 +1143,7 @@ Symbol *DirectiveAttributeVisitor<T>::DeclareNewAccessEntity(
 template <typename T>
 Symbol *DirectiveAttributeVisitor<T>::DeclareNewAccessEntity(
     const Symbol &object, Symbol::Flag flag, Scope &scope) {
-  auto &symbol{MakeAssocSymbol(object.name(), object, scope)};
-  symbol.set(flag);
-  if (flag == Symbol::Flag::OmpCopyIn) {
-    // The symbol in copyin clause must be threadprivate entity.
-    symbol.set(Symbol::Flag::OmpThreadprivate);
-  }
-  return &symbol;
+  return DeclareNewAccessEntity(object.name(), object, flag, scope);
 }
 
 template <typename T>
diff --git a/flang/test/Semantics/OpenMP/use-rename-array-dsa.f90 b/flang/test/Semantics/OpenMP/use-rename-array-dsa.f90
index 865cdff2eeb24..044e6063c4dfc 100644
--- a/flang/test/Semantics/OpenMP/use-rename-array-dsa.f90
+++ b/flang/test/Semantics/OpenMP/use-rename-array-dsa.f90
@@ -26,7 +26,9 @@ program test
     end do
   !$omp end parallel do
 end program
-! The loop variable is private and predetermined.
-! CHECK: i (OmpPrivate, OmpPreDetermined): HostAssoc
 ! The OMP region must create a host-association for s_ary under its alias name.
-! CHECK: s_ary (OmpShared): HostAssoc
+! CHECK:  MainProgram scope: TEST
+! CHECK:    OtherConstruct scope:
+! CHECK:      ary (OmpShared): HostAssoc => ary
+! CHECK:      i (OmpPrivate, OmpPreDetermined): HostAssoc => i
+! CHECK:      s_ary (OmpShared): HostAssoc => ary



More information about the flang-commits mailing list