[flang-commits] [flang] [Flang][OpenMP] Fix visibility of user-defined reductions for derived types and module imports (PR #180552)
CHANDRA GHALE via flang-commits
flang-commits at lists.llvm.org
Mon Feb 9 07:54:27 PST 2026
https://github.com/chandraghale created https://github.com/llvm/llvm-project/pull/180552
User-defined reductions declared in a module were not visible to programs that imported the module via USE statements, causing valid code to be incorrectly rejected. The reduction identifier defined in the module scope wasn't being found during semantic analysis of the main program.
Ref:
OpenMP Spec 5.1
_"If a directive appears in the specification part of a module then the behavior is as if that directive,
with the variables, types and procedures that have PRIVATE accessibility omitted, appears in the
specification part of any compilation unit that references the module unless otherwise specified "_
Fixes : [https://github.com/llvm/llvm-project/issues/176279](https://github.com/llvm/llvm-project/issues/176279)
>From 36569511465cb4e4920bacc51a31e9eb059fef3c Mon Sep 17 00:00:00 2001
From: Chandra Ghale <ghale at pe31.hpc.amslabs.hpecorp.net>
Date: Mon, 9 Feb 2026 09:48:33 -0600
Subject: [PATCH] Fix visibility of user-defined reductions for derived types
and module imports
---
flang/include/flang/Semantics/symbol.h | 16 ++++++++++
flang/lib/Semantics/check-omp-structure.cpp | 14 +++++++++
.../declare-reduction-derived-module.f90 | 30 +++++++++++++++++++
3 files changed, 60 insertions(+)
create mode 100644 flang/test/Semantics/OpenMP/declare-reduction-derived-module.f90
diff --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h
index 95efe1ae2bd5e..4c422ac5f471a 100644
--- a/flang/include/flang/Semantics/symbol.h
+++ b/flang/include/flang/Semantics/symbol.h
@@ -764,6 +764,22 @@ class UserReductionDetails {
return true;
}
}
+ // For derived and class-derived types, match on the type symbol pointer.
+ if (type.category() == DeclTypeSpec::TypeDerived ||
+ type.category() == DeclTypeSpec::ClassDerived) {
+ const auto &rhs = type.derivedTypeSpec();
+ const auto &rhsSym = rhs.typeSymbol();
+ for (auto t : typeList_) {
+ if (t->category() == DeclTypeSpec::TypeDerived ||
+ t->category() == DeclTypeSpec::ClassDerived) {
+ const auto &lhs = t->derivedTypeSpec();
+ const auto &lhsSym = lhs.typeSymbol();
+ if (&lhsSym == &rhsSym) {
+ return true;
+ }
+ }
+ }
+ }
return false;
}
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 5c4b5bb756734..0e004a8e26501 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -3691,6 +3691,20 @@ static bool CheckSymbolSupportsType(const Scope &scope,
return reductionDetails->SupportsType(type);
}
}
+ // Look through module scopes in the global scope.
+ // This covers reductions declared in a module and used via USE association
+ const SemanticsContext &semCtx{scope.context()};
+ Scope &global = const_cast<SemanticsContext &>(semCtx).globalScope();
+ for (const Scope &child : global.children()) {
+ if (child.kind() == Scope::Kind::Module) {
+ if (const auto *symbol{child.FindSymbol(name)}) {
+ if (const auto *reductionDetails{
+ symbol->detailsIf<UserReductionDetails>()}) {
+ return reductionDetails->SupportsType(type);
+ }
+ }
+ }
+ }
return false;
}
diff --git a/flang/test/Semantics/OpenMP/declare-reduction-derived-module.f90 b/flang/test/Semantics/OpenMP/declare-reduction-derived-module.f90
new file mode 100644
index 0000000000000..342301ba2a8da
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/declare-reduction-derived-module.f90
@@ -0,0 +1,30 @@
+! RUN: %flang_fc1 -fdebug-dump-symbols -fopenmp -fopenmp-version=50 %s | FileCheck %s
+module mod
+ type t
+ integer::i=0
+ end type t
+!$omp declare reduction (+:t:omp_out%i=omp_out%i+omp_in%i) &
+!$omp initializer(omp_priv%i=0)
+end module mod
+
+!CHECK: Module scope: mod
+!CHECK: op.+, PUBLIC: UserReductionDetails TYPE(t)
+!CHECK: t, PUBLIC: DerivedType components: i
+
+program main
+ use mod
+ integer::i
+ type(t)::x1
+ x1%i=0
+!$omp parallel do reduction(+:x1)
+ do i=1,10
+ x1%i=x1%i+1
+ end do
+!$omp end parallel do
+ print *,'pass'
+end program main
+
+!CHECK: MainProgram scope: MAIN
+!CHECK: op.+: Use from op.+ in mod
+!CHECK: t: Use from t in mod
+!CHECK: x1 size=4 offset=4: ObjectEntity type: TYPE(t)
More information about the flang-commits
mailing list