[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
Sun Apr 5 05:19:22 PDT 2026


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

>From b30f6631209a0fd38a3474b79283a0d20eed6d9a Mon Sep 17 00:00:00 2001
From: Aditya Trivedi <adit4443ya at gmail.com>
Date: Sun, 5 Apr 2026 11:26:59 +0000
Subject: [PATCH] [Flang][OpenMP] Fix rank mismatch for USE-renamed arrays in
 OpenMP regions When a module array is imported with a local alias via USE
 renaming (e.g. USE mod, ONLY: s_ary => ary), the OpenMP implicit symbol
 resolution was incorrectly creating the new scoped symbol using the ultimate
 symbol's name ("ary") rather than the local alias ("s_ary"). This is fixed by
 maintaining host-association directly to the local USE-renamed symbol
 (ensuring local scope modifications track correctly) instead of bypassing it
 for the ultimate origin symbol, resolving the dimension collision error.
 Fixes #185344

---
 flang/lib/Semantics/resolve-directives.cpp    | 22 +++++++---
 .../Semantics/OpenMP/use-rename-array-dsa.f90 | 40 +++++++++++++++++++
 2 files changed, 57 insertions(+), 5 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 fb241d2606b47..ea70beac9ca73 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -174,6 +174,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 &);
   Symbol *DeclareOrMarkOtherAccessEntity(const parser::Name &, Symbol::Flag);
@@ -1209,9 +1211,10 @@ 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(object.name(), object, scope)};
+  auto &symbol{MakeAssocSymbol(name, object, scope)};
   symbol.set(flag);
   if (flag == Symbol::Flag::OmpCopyIn) {
     // The symbol in copyin clause must be threadprivate entity.
@@ -1220,6 +1223,12 @@ Symbol *DirectiveAttributeVisitor<T>::DeclareNewAccessEntity(
   return &symbol;
 }
 
+template <typename T>
+Symbol *DirectiveAttributeVisitor<T>::DeclareNewAccessEntity(
+    const Symbol &object, Symbol::Flag flag, Scope &scope) {
+  return DeclareNewAccessEntity(object.name(), object, flag, scope);
+}
+
 template <typename T>
 Symbol *DirectiveAttributeVisitor<T>::DeclareAccessEntity(
     const parser::Name &name, Symbol::Flag flag, Scope &scope) {
@@ -2736,12 +2745,15 @@ void OmpAttributeVisitor::CreateImplicitSymbols(
     // This would make x appear to be defined in p2, causing it to be
     // privatized in p2 and its privatization in p1 to be skipped.
     auto makeSymbol = [&](Symbol::Flags flags) {
-      const Symbol *hostSymbol =
-          lastDeclSymbol ? lastDeclSymbol : &symbol->GetUltimate();
+      const Symbol *hostSymbol = lastDeclSymbol ? lastDeclSymbol : &symbol->GetUltimate();
+      const SourceName &name =
+          (symbol->name().ToString() != hostSymbol->name().ToString())
+          ? symbol->name()
+          : hostSymbol->name();
       assert(flags.LeastElement());
       Symbol::Flag flag = *flags.LeastElement();
       lastDeclSymbol = DeclareNewAccessEntity(
-          *hostSymbol, flag, context_.FindScope(dirContext.directiveSource));
+          name, *hostSymbol, flag, context_.FindScope(dirContext.directiveSource));
       lastDeclSymbol->flags() |= flags;
       return lastDeclSymbol;
     };
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..f17584609a273
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/use-rename-array-dsa.f90
@@ -0,0 +1,40 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+
+! Check that compiling a USE-renamed array inside an OpenMP construct
+! does not trigger a dimension mismatch error against the original symbol name.
+! Also serves as a check that host-association for implicitly scoped variables
+! links against the local 'use' alias symbol correctly.
+
+module mod1
+  implicit none
+  real(8), allocatable :: ary(:,:,:)
+end module mod1
+
+module mod2
+  implicit none
+  real(8), allocatable :: ary(:,:,:,:,:)
+end module mod2
+
+module mod3
+  implicit none
+contains
+  subroutine sub(arg)
+    use mod1, only: s_ary => ary
+    use mod2, only: ary
+    implicit none
+    integer(4), intent(in) :: arg
+    integer(4) :: i, j, k
+    integer(4) :: xx, yy, zs, ze, mm
+
+    !$omp parallel do
+    do j = 0, yy+1
+      do i = 0, xx+1
+        do k = zs, ze
+          s_ary(k,i,j) = s_ary(k,i,j) + ary(k,-1,i,j,mm)
+          ary(k,-1,i,j,mm) = 0._8
+        end do
+      end do
+    end do
+    !$omp end parallel do
+  end subroutine sub
+end module mod3



More information about the flang-commits mailing list