[flang-commits] [flang] 3e7c207 - [Flang][OpenMP] Fix DEFAULT(NONE) check for Cray pointers in nested OpenMP directives (#190764)
via flang-commits
flang-commits at lists.llvm.org
Wed Apr 22 02:37:51 PDT 2026
Author: Urvi Rav
Date: 2026-04-22T15:07:47+05:30
New Revision: 3e7c207ebe359a7e02b7247b0f24578b17d18eae
URL: https://github.com/llvm/llvm-project/commit/3e7c207ebe359a7e02b7247b0f24578b17d18eae
DIFF: https://github.com/llvm/llvm-project/commit/3e7c207ebe359a7e02b7247b0f24578b17d18eae.diff
LOG: [Flang][OpenMP] Fix DEFAULT(NONE) check for Cray pointers in nested OpenMP directives (#190764)
Fixes - [#190750](https://github.com/llvm/llvm-project/issues/190750)
In resolve-directives.cpp, the handling of DEFAULT(NONE) for Cray
pointers in nested OpenMP regions was incomplete.
The existing implementation only checked the data-sharing attribute
(DSA) of the Cray pointee, and did not account for the associated Cray
pointer. This led to incorrect diagnostics when the pointee was used
inside a region, but the pointer’s DSA was not properly considered.
This patch updates the logic to:
1. Check DSAs for both the Cray pointee and its corresponding pointer
2. Restrict the validation to the current directive context, ensuring
that each default(none) region enforces its own data-sharing
requirements
3. Introduce a helper (initSymbolDSA) to reuse DSA lookup logic
With this change, nested default(none) regions correctly require the
Cray pointer to be explicitly listed in each region, and diagnostics are
issued when either the pointer or pointee is missing a DSA in the
current context.
A test case has also been added to cover this scenario.
Co-authored-by: Leandro Lupori
<[leandro.lupori at linaro.org](mailto:leandro.lupori at linaro.org)>
---------
Co-authored-by: Michael Klemm <michael.klemm at amd.com>
Added:
flang/test/Semantics/OpenMP/cray-pointer-default-none.f90
Modified:
flang/lib/Semantics/resolve-directives.cpp
flang/test/Semantics/OpenMP/cray-pointer-usage.f90
Removed:
################################################################################
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index a110607c3c72e..37da0b3bdaa1f 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -2461,20 +2461,24 @@ void OmpAttributeVisitor::CreateImplicitSymbols(
Symbol::Flags dsa;
Scope &scope{context_.FindScope(dirContext.directiveSource)};
- auto it{scope.find(symbol->name())};
- if (it != scope.end()) {
- // There is already a symbol in the current scope, use its DSA.
- dsa = GetSymbolDSA(*it->second);
- } else {
- for (auto symMap : dirContext.objectWithDSA) {
- if (symMap.first->name() == symbol->name()) {
- // `symbol` already has a data-sharing attribute in the current
- // context, use it.
- dsa.set(symMap.second);
- break;
+
+ auto initSymbolDSA = [&](const Symbol *sym, Symbol::Flags &dsa) {
+ auto it{scope.find(sym->name())};
+ if (it != scope.end()) {
+ // There is already a symbol in the current scope, use its DSA.
+ dsa = GetSymbolDSA(*it->second);
+ } else {
+ for (auto symMap : dirContext.objectWithDSA) {
+ if (symMap.first->name() == sym->name()) {
+ // `sym` already has a data-sharing attribute in the current
+ // context, use it.
+ dsa.set(symMap.second);
+ break;
+ }
}
}
- }
+ };
+ initSymbolDSA(symbol, dsa);
// When handling each implicit rule for a given symbol, one of the
// following actions may be taken:
@@ -2542,27 +2546,35 @@ void OmpAttributeVisitor::CreateImplicitSymbols(
LLVM_DEBUG(llvm::dbgs()
<< "HasStaticStorageDuration(" << symbol->name() << "):\n");
- if ((checkDefaultNone = checkDefaultNone |
- (dsa.none() &&
- dirContext.defaultDSA == Symbol::Flag::OmpNone))) {
+ const Symbol *crayPtr = nullptr;
+ Symbol::Flags crayPtrDSA;
+ if (symbol->GetUltimate().test(Symbol::Flag::CrayPointee)) {
+ crayPtr =
+ currScope().FindSymbol(semantics::GetCrayPointer(*symbol).name());
+ if (crayPtr) {
+ initSymbolDSA(crayPtr, crayPtrDSA);
+ }
+ }
+ if (dsa.none() && crayPtrDSA.none() &&
+ dirContext.defaultDSA == Symbol::Flag::OmpNone) {
+ checkDefaultNone = true;
+ }
+ if (checkDefaultNone) {
auto defaultNoneError = [&](parser::CharBlock loc, const Symbol *sym) {
- if (sym->GetUltimate().test(Symbol::Flag::CrayPointee)) {
- std::string crayPtrName{
- semantics::GetCrayPointer(*sym).name().ToString()};
- if (!IsObjectWithDSA(*currScope().FindSymbol(crayPtrName))) {
- context_.Say(loc,
- "The DEFAULT(NONE) clause requires that the Cray Pointer '%s' must be listed in a data-sharing attribute clause"_err_en_US,
- crayPtrName);
- }
+ if (crayPtr) {
+ context_.Say(loc,
+ "The DEFAULT(NONE) clause requires that the Cray Pointer '%s' must be listed in a data-sharing attribute clause"_err_en_US,
+ crayPtr->name());
} else {
context_.Say(loc,
"The DEFAULT(NONE) clause requires that '%s' must be listed in a data-sharing attribute clause"_err_en_US,
sym->name());
}
};
- if (dsa.test(Symbol::Flag::OmpPrivate)) {
+ if (dsa.test(Symbol::Flag::OmpPrivate) ||
+ crayPtrDSA.test(Symbol::Flag::OmpPrivate)) {
checkDefaultNone = false;
- } else if (dsa.any()) {
+ } else if (dsa.any() || crayPtrDSA.any()) {
defaultNoneError(dirContext.directiveSource, symbol);
} else if (dirDepth == (int)dirContext_.size() - 1) {
defaultNoneError(name.source, symbol);
diff --git a/flang/test/Semantics/OpenMP/cray-pointer-default-none.f90 b/flang/test/Semantics/OpenMP/cray-pointer-default-none.f90
new file mode 100644
index 0000000000000..301411dd3968b
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/cray-pointer-default-none.f90
@@ -0,0 +1,158 @@
+!RUN: %python %S/../test_errors.py %s %flang -fopenmp
+
+! None of the below tests should fail.
+
+subroutine none_shared()
+ implicit none
+ integer var(*)
+ pointer(ivar,var)
+ integer pointee(8)
+
+ pointee(1) = 42
+ ivar = loc(pointee)
+
+ !$omp parallel num_threads(1) default(none) shared(ivar)
+ var(1) = var(1) / 2
+ print '(A24,I6)', 'none_shared', var(1)
+ !$omp end parallel
+end subroutine
+
+subroutine none_private()
+ implicit none
+ integer var(*)
+ pointer(ivar,var)
+ integer pointee(8)
+
+ pointee(1) = 42
+ ivar = loc(pointee)
+
+ !$omp parallel num_threads(1) default(none) private(ivar) shared(pointee)
+ ivar = loc(pointee)
+ var(1) = var(1) / 2
+ print '(A24,I6)', 'none_private', var(1)
+ !$omp end parallel
+end subroutine
+
+subroutine none_firstprivate()
+ implicit none
+ integer var(*)
+ pointer(ivar,var)
+ integer pointee(8)
+
+ pointee(1) = 42
+ ivar = loc(pointee)
+
+ !$omp parallel num_threads(1) default(none) firstprivate(ivar)
+ var(1) = var(1) / 2
+ print '(A24,I6)', 'none_firstprivate', var(1)
+ !$omp end parallel
+end subroutine
+
+subroutine private_shared()
+ implicit none
+ integer var(*)
+ pointer(ivar,var)
+ integer pointee(8)
+
+ pointee(1) = 42
+ ivar = loc(pointee)
+
+ !$omp parallel num_threads(1) default(private) shared(ivar)
+ var(1) = var(1) / 2
+ print '(A24,I6)', 'private_shared', var(1)
+ !$omp end parallel
+end subroutine
+
+subroutine private_firstprivate()
+ implicit none
+ integer var(*)
+ pointer(ivar,var)
+ integer pointee(8)
+
+ pointee(1) = 42
+ ivar = loc(pointee)
+
+ !$omp parallel num_threads(1) default(private) firstprivate(ivar)
+ var(1) = var(1) / 2
+ print '(A24,I6)', 'private_firstprivate', var(1)
+ !$omp end parallel
+end subroutine
+
+subroutine firstprivate_shared()
+ implicit none
+ integer var(*)
+ pointer(ivar,var)
+ integer pointee(8)
+
+ pointee(1) = 42
+ ivar = loc(pointee)
+
+ !$omp parallel num_threads(1) default(firstprivate) shared(ivar)
+ var(1) = var(1) / 2
+ print '(A24,I6)', 'firstprivate_shared', var(1)
+ !$omp end parallel
+end subroutine
+
+subroutine firstprivate_private()
+ implicit none
+ integer var(*)
+ pointer(ivar,var)
+ integer pointee(8)
+
+ pointee(1) = 42
+ ivar = loc(pointee)
+
+ !$omp parallel num_threads(1) default(firstprivate) private(ivar) shared(pointee)
+ ivar = loc(pointee)
+ var(1) = var(1) / 2
+ print '(A24,I6)', 'firstprivate_private', var(1)
+ !$omp end parallel
+end subroutine
+
+subroutine loop_common_none_shared()
+ implicit none
+ common /cmn/ mp
+ real a(1)
+ pointer(mp,a)
+ integer i
+
+ !$omp parallel num_threads(1) default(none) shared(mp)
+ !$omp do
+ do i = 1,10
+ a(1) = a(1) / 2
+ end do
+ print '(A24,I6)', 'none_shared', a(1)
+ !$omp end parallel
+end subroutine
+
+subroutine loop_common_firstprivate()
+ implicit none
+ common /cmn/ ptr
+ real a(1)
+ pointer(ptr,a)
+ integer i
+
+ !$omp parallel num_threads(1) default(firstprivate) shared(ptr)
+ !$omp do
+ do i = 1,10
+ a(1) = a(1) / 2
+ end do
+ print '(A24,I6)', 'none_shared', a(1)
+ !$omp end parallel
+end subroutine
+
+subroutine loop_common_private()
+ implicit none
+ common /cmn/ ptr
+ real a(1)
+ pointer(ptr,a)
+ integer i
+
+ !$omp parallel num_threads(1) default(firstprivate) private(ptr)
+ !$omp do
+ do i = 1,10
+ a(1) = a(1) / 2
+ end do
+ print '(A24,I6)', 'none_shared', a(1)
+ !$omp end parallel
+end subroutine
diff --git a/flang/test/Semantics/OpenMP/cray-pointer-usage.f90 b/flang/test/Semantics/OpenMP/cray-pointer-usage.f90
index 06211da315fcb..a5064515104aa 100644
--- a/flang/test/Semantics/OpenMP/cray-pointer-usage.f90
+++ b/flang/test/Semantics/OpenMP/cray-pointer-usage.f90
@@ -46,3 +46,38 @@ subroutine test_cray_pointer_usage
print *, var(1)
!$omp end parallel
end subroutine test_cray_pointer_usage
+
+subroutine test_nested_cray_pointer
+ implicit none
+ real :: X, B
+ pointer(P, B)
+
+ X = 1.0
+ P = loc(X)
+
+ !$omp parallel default(none) shared(P, X)
+ !$omp critical
+ B = B + 2.0
+ !$omp end critical
+ !$omp end parallel
+
+ !$omp parallel default(none) shared(P, X)
+ !$omp parallel default(none)
+ ! ERROR: The DEFAULT(NONE) clause requires that the Cray Pointer 'p' must be listed in a data-sharing attribute clause
+ B = B + 1.0
+ !$omp end parallel
+ !$omp end parallel
+
+ !$omp parallel default(none) shared(P, X)
+ !$omp parallel default(none) shared(P, X)
+ B = B + 1.0
+ !$omp end parallel
+ !$omp end parallel
+
+ !$omp parallel default(none)
+ ! ERROR: The DEFAULT(NONE) clause requires that the Cray Pointer 'p' must be listed in a data-sharing attribute clause
+ !$omp parallel default(none) shared(P)
+ B = B + 1.0
+ !$omp end parallel
+ !$omp end parallel
+end subroutine test_nested_cray_pointer
More information about the flang-commits
mailing list