[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