[flang-commits] [flang] [Flang][OpenMP] DEFAULT(NONE) error checking on implicit references (PR #182214)
Phoebe Linck via flang-commits
flang-commits at lists.llvm.org
Mon Mar 2 12:46:34 PST 2026
https://github.com/phi-bee updated https://github.com/llvm/llvm-project/pull/182214
>From 9ae4a47a9fa3db9ed78f878077c2bec48910695f Mon Sep 17 00:00:00 2001
From: Phoebe Linck <phoebe.linck at hpe.com>
Date: Tue, 17 Feb 2026 21:42:29 -0600
Subject: [PATCH 1/2] Default(none) error checking on implicit symbols
---
flang/lib/Semantics/resolve-directives.cpp | 44 +++++++++++-----------
flang/test/Semantics/OpenMP/resolve05.f90 | 13 +++++++
2 files changed, 36 insertions(+), 21 deletions(-)
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 1fde0d62581e8..45aced325c8eb 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -1142,7 +1142,7 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
void IssueNonConformanceWarning(llvm::omp::Directive D,
parser::CharBlock source, unsigned EmitFromVersion);
- void CreateImplicitSymbols(const Symbol *symbol);
+ void CreateImplicitSymbols(const parser::Name &, const Symbol *symbol);
void AddToContextObjectWithExplicitDSA(Symbol &symbol, Symbol::Flag flag) {
AddToContextObjectWithDSA(symbol, flag);
@@ -2795,7 +2795,8 @@ static bool IsTargetCaptureImplicitlyFirstprivatizeable(const Symbol &symbol,
symbol.details());
}
-void OmpAttributeVisitor::CreateImplicitSymbols(const Symbol *symbol) {
+void OmpAttributeVisitor::CreateImplicitSymbols(
+ const parser::Name &name, const Symbol *symbol) {
if (!IsPrivatizable(symbol)) {
return;
}
@@ -2922,6 +2923,25 @@ void OmpAttributeVisitor::CreateImplicitSymbols(const Symbol *symbol) {
// Ideally, lowering should be changed and all implicit symbols
// should be marked with OmpImplicit.
+ if (dirContext.defaultDSA == Symbol::Flag::OmpNone) {
+ if (!symbol->GetUltimate().test(Symbol::Flag::OmpThreadprivate) &&
+ !symbol->test(Symbol::Flag::OmpPrivate)) {
+ if (symbol->GetUltimate().test(Symbol::Flag::CrayPointee)) {
+ std::string crayPtrName{
+ semantics::GetCrayPointer(*symbol).name().ToString()};
+ if (!IsObjectWithDSA(*currScope().FindSymbol(crayPtrName))) {
+ context_.Say(name.source,
+ "The DEFAULT(NONE) clause requires that the Cray Pointer '%s' must be listed in a data-sharing attribute clause"_err_en_US,
+ crayPtrName);
+ }
+ } else {
+ context_.Say(name.source,
+ "The DEFAULT(NONE) clause requires that '%s' must be listed in a data-sharing attribute clause"_err_en_US,
+ symbol->name());
+ }
+ }
+ }
+
if (dirContext.defaultDSA == Symbol::Flag::OmpPrivate ||
dirContext.defaultDSA == Symbol::Flag::OmpFirstPrivate ||
dirContext.defaultDSA == Symbol::Flag::OmpShared) {
@@ -3052,24 +3072,6 @@ void OmpAttributeVisitor::Post(const parser::Name &name) {
if (Symbol * found{currScope().FindSymbol(name.source)}) {
if (symbol != found) {
name.symbol = found; // adjust the symbol within region
- } else if (GetContext().defaultDSA == Symbol::Flag::OmpNone &&
- !symbol->GetUltimate().test(Symbol::Flag::OmpThreadprivate) &&
- // Exclude indices of sequential loops that are privatised in
- // the scope of the parallel region, and not in this scope.
- // TODO: check whether this should be caught in IsObjectWithDSA
- !symbol->test(Symbol::Flag::OmpPrivate)) {
- if (symbol->GetUltimate().test(Symbol::Flag::CrayPointee)) {
- std::string crayPtrName{
- semantics::GetCrayPointer(*symbol).name().ToString()};
- if (!IsObjectWithDSA(*currScope().FindSymbol(crayPtrName)))
- context_.Say(name.source,
- "The DEFAULT(NONE) clause requires that the Cray Pointer '%s' must be listed in a data-sharing attribute clause"_err_en_US,
- crayPtrName);
- } else {
- context_.Say(name.source,
- "The DEFAULT(NONE) clause requires that '%s' must be listed in a data-sharing attribute clause"_err_en_US,
- symbol->name());
- }
}
}
}
@@ -3123,7 +3125,7 @@ void OmpAttributeVisitor::Post(const parser::Name &name) {
// we don't need to do anything here (i.e. no flags are needed or
// anything else).
if (!IsLocalInsideScope(*symbol, currScope())) {
- CreateImplicitSymbols(symbol);
+ CreateImplicitSymbols(name, symbol);
}
} // within OpenMP construct
}
diff --git a/flang/test/Semantics/OpenMP/resolve05.f90 b/flang/test/Semantics/OpenMP/resolve05.f90
index c4cebb48ac5c2..80e6ce964bba4 100644
--- a/flang/test/Semantics/OpenMP/resolve05.f90
+++ b/flang/test/Semantics/OpenMP/resolve05.f90
@@ -29,8 +29,21 @@ subroutine default_none_seq_loop
enddo
end subroutine
+! Test that DEFAULT(NONE) error check sees implicit references
+subroutine default_none_nested()
+ integer :: a
+
+ !$omp parallel default(none)
+ !$omp task
+ !ERROR: The DEFAULT(NONE) clause requires that 'a' must be listed in a data-sharing attribute clause
+ a = 1
+ !$omp end task
+ !$omp end parallel
+end subroutine default_none_nested
+
program mm
call default_none()
call default_none_seq_loop()
+ call default_none_nested()
!TODO: private, firstprivate, shared
end
>From 6fc01b038ee30dfb248e580372409a84c9a4dfc5 Mon Sep 17 00:00:00 2001
From: Phoebe Linck <phoebe.linck at hpe.com>
Date: Thu, 26 Feb 2026 10:57:33 -0600
Subject: [PATCH 2/2] Refactor default(none) check
---
flang/lib/Semantics/resolve-directives.cpp | 57 ++++++++++++++--------
1 file changed, 38 insertions(+), 19 deletions(-)
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 45aced325c8eb..0dd5986f606cc 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -2807,6 +2807,7 @@ void OmpAttributeVisitor::CreateImplicitSymbols(
// OMP 5.2 5.1.1 - Variables Referenced in a Construct
Symbol *lastDeclSymbol = nullptr;
Symbol::Flags prevDSA;
+ bool checkDefaultNone = false;
for (int dirDepth{0}; dirDepth < (int)dirContext_.size(); ++dirDepth) {
DirContext &dirContext = dirContext_[dirDepth];
Symbol::Flags dsa;
@@ -2827,6 +2828,9 @@ void OmpAttributeVisitor::CreateImplicitSymbols(
}
}
+ checkDefaultNone = checkDefaultNone |
+ (dsa.none() && dirContext.defaultDSA == Symbol::Flag::OmpNone);
+
// When handling each implicit rule for a given symbol, one of the
// following actions may be taken:
// 1. Declare a new private or shared symbol.
@@ -2893,6 +2897,40 @@ void OmpAttributeVisitor::CreateImplicitSymbols(
LLVM_DEBUG(llvm::dbgs()
<< "HasStaticStorageDuration(" << symbol->name() << "):\n");
+ if (checkDefaultNone) {
+ if (dsa.test(Symbol::Flag::OmpPrivate)) {
+ checkDefaultNone = false;
+ } else if (dsa.any()) {
+ if (symbol->GetUltimate().test(Symbol::Flag::CrayPointee)) {
+ std::string crayPtrName{
+ semantics::GetCrayPointer(*symbol).name().ToString()};
+ if (!IsObjectWithDSA(*currScope().FindSymbol(crayPtrName))) {
+ context_.Say(dirContext.directiveSource,
+ "The DEFAULT(NONE) clause requires that the Cray Pointer '%s' must be listed in a data-sharing attribute clause"_err_en_US,
+ crayPtrName);
+ }
+ } else {
+ context_.Say(dirContext.directiveSource,
+ "The DEFAULT(NONE) clause requires that '%s' must be listed in a data-sharing attribute clause"_err_en_US,
+ symbol->name());
+ }
+ } else if (dirDepth == (int)dirContext_.size() - 1) {
+ if (symbol->GetUltimate().test(Symbol::Flag::CrayPointee)) {
+ std::string crayPtrName{
+ semantics::GetCrayPointer(*symbol).name().ToString()};
+ if (!IsObjectWithDSA(*currScope().FindSymbol(crayPtrName))) {
+ context_.Say(name.source,
+ "The DEFAULT(NONE) clause requires that the Cray Pointer '%s' must be listed in a data-sharing attribute clause"_err_en_US,
+ crayPtrName);
+ }
+ } else {
+ context_.Say(name.source,
+ "The DEFAULT(NONE) clause requires that '%s' must be listed in a data-sharing attribute clause"_err_en_US,
+ symbol->name());
+ }
+ }
+ }
+
if (dsa.any()) {
if (parallelDir || taskGenDir || teamsDir) {
Symbol *prevDeclSymbol{lastDeclSymbol};
@@ -2923,25 +2961,6 @@ void OmpAttributeVisitor::CreateImplicitSymbols(
// Ideally, lowering should be changed and all implicit symbols
// should be marked with OmpImplicit.
- if (dirContext.defaultDSA == Symbol::Flag::OmpNone) {
- if (!symbol->GetUltimate().test(Symbol::Flag::OmpThreadprivate) &&
- !symbol->test(Symbol::Flag::OmpPrivate)) {
- if (symbol->GetUltimate().test(Symbol::Flag::CrayPointee)) {
- std::string crayPtrName{
- semantics::GetCrayPointer(*symbol).name().ToString()};
- if (!IsObjectWithDSA(*currScope().FindSymbol(crayPtrName))) {
- context_.Say(name.source,
- "The DEFAULT(NONE) clause requires that the Cray Pointer '%s' must be listed in a data-sharing attribute clause"_err_en_US,
- crayPtrName);
- }
- } else {
- context_.Say(name.source,
- "The DEFAULT(NONE) clause requires that '%s' must be listed in a data-sharing attribute clause"_err_en_US,
- symbol->name());
- }
- }
- }
-
if (dirContext.defaultDSA == Symbol::Flag::OmpPrivate ||
dirContext.defaultDSA == Symbol::Flag::OmpFirstPrivate ||
dirContext.defaultDSA == Symbol::Flag::OmpShared) {
More information about the flang-commits
mailing list