[flang-commits] [flang] [flang][OpenMP] Do not emit an error for CRITICAL inside DEFAULT(NONE) (PR #216403)

Leandro Lupori via flang-commits flang-commits at lists.llvm.org
Fri Aug 21 10:21:37 PDT 2026


https://github.com/luporl updated https://github.com/llvm/llvm-project/pull/216403

>From 0e7ab9926d42194e0b163b5de687e5426c9d81f7 Mon Sep 17 00:00:00 2001
From: Leandro Lupori <leandro.lupori at linaro.org>
Date: Fri, 14 Aug 2026 17:56:57 -0300
Subject: [PATCH 1/3] [flang][OpenMP] Do not emit an error for CRITICAL inside
 DEFAULT(NONE)

Fixes #197394
---
 flang/lib/Semantics/resolve-directives.cpp    | 16 +++++++++++--
 flang/test/Semantics/OpenMP/default-none.f90  | 12 ++++++++++
 .../test/Semantics/OpenMP/default-none02.f90  | 23 +++++++++++++++++++
 3 files changed, 49 insertions(+), 2 deletions(-)
 create mode 100644 flang/test/Semantics/OpenMP/default-none02.f90

diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 15bb84d7e486f..fa7d2b1957b91 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -2725,6 +2725,7 @@ void OmpAttributeVisitor::CreateImplicitSymbols(
         dirContext.defaultDSA == Symbol::Flag::OmpNone) {
       checkDefaultNone = true;
     }
+    bool hasDefaultNoneError{false};
     if (checkDefaultNone) {
       auto defaultNoneError = [&](parser::CharBlock loc, const Symbol *sym) {
         if (crayPtr) {
@@ -2736,6 +2737,7 @@ void OmpAttributeVisitor::CreateImplicitSymbols(
               "The DEFAULT(NONE) clause requires that '%s' must be listed in a data-sharing attribute clause"_err_en_US,
               sym->name());
         }
+        hasDefaultNoneError = true;
       };
       if (dsa.test(Symbol::Flag::OmpPrivate) ||
           crayPtrDSA.test(Symbol::Flag::OmpPrivate)) {
@@ -2779,14 +2781,18 @@ void OmpAttributeVisitor::CreateImplicitSymbols(
 
     if (dirContext.defaultDSA == Symbol::Flag::OmpPrivate ||
         dirContext.defaultDSA == Symbol::Flag::OmpFirstPrivate ||
-        dirContext.defaultDSA == Symbol::Flag::OmpShared) {
+        dirContext.defaultDSA == Symbol::Flag::OmpShared ||
+        (dirContext.defaultDSA == Symbol::Flag::OmpNone &&
+            !hasDefaultNoneError)) {
       // 1) default
       // Allowed only with parallel, teams and task generating constructs.
       if (!parallelDir && !taskGenDir && !teamsDir) {
         return;
       }
       dsa = {dirContext.defaultDSA};
-      makeSymbol(dsa);
+      if (dirContext.defaultDSA != Symbol::Flag::OmpNone) {
+        makeSymbol(dsa);
+      }
       PRINT_IMPLICIT_RULE("1) default");
     } else if (parallelDir) {
       // 2) parallel -> shared
@@ -2828,6 +2834,12 @@ void OmpAttributeVisitor::CreateImplicitSymbols(
         PRINT_IMPLICIT_RULE("7) taskgen: firstprivate");
       }
     }
+    if (hasDefaultNoneError &&
+        (dsa.none() || dsa == Symbol::Flags{Symbol::Flag::OmpNone})) {
+      // Set DSA to avoid reporting the same error multiple times.
+      dsa = {Symbol::Flag::OmpShared};
+      makeSymbol(dsa);
+    }
     prevDSA = dsa;
   }
 }
diff --git a/flang/test/Semantics/OpenMP/default-none.f90 b/flang/test/Semantics/OpenMP/default-none.f90
index a56657ccee467..0eb6e22ebd7ab 100644
--- a/flang/test/Semantics/OpenMP/default-none.f90
+++ b/flang/test/Semantics/OpenMP/default-none.f90
@@ -73,3 +73,15 @@ subroutine internal()
 !$omp end parallel
   end subroutine internal
 end subroutine host_assoc
+
+subroutine parallel_critical()
+  integer :: i
+  !$omp parallel default(none)
+  !$omp critical
+  !$omp parallel
+    do i = 1, 10
+    end do
+  !$omp end parallel
+  !$omp end critical
+  !$omp end parallel
+end subroutine
diff --git a/flang/test/Semantics/OpenMP/default-none02.f90 b/flang/test/Semantics/OpenMP/default-none02.f90
new file mode 100644
index 0000000000000..d2d2c876af65c
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/default-none02.f90
@@ -0,0 +1,23 @@
+!RUN: %python %S/../test_errors.py %s %flang -fopenmp
+! Negative tests for default(none)
+
+! Check that the same error is not displayed for every use of a symbol.
+subroutine repeated_error()
+  real :: B
+
+  !$omp parallel default(none)
+    ! ERROR: The DEFAULT(NONE) clause requires that 'b' must be listed in a data-sharing attribute clause
+    B = B + 1.0 + B
+  !$omp end parallel
+
+  !$omp parallel default(none)
+  !$omp critical
+    ! ERROR: The DEFAULT(NONE) clause requires that 'b' must be listed in a data-sharing attribute clause
+    B = B + 2.0 + B
+    !$omp parallel default(none)
+      ! ERROR: The DEFAULT(NONE) clause requires that 'b' must be listed in a data-sharing attribute clause
+      B = B + 3.0 + B
+    !$omp end parallel
+  !$omp end critical
+  !$omp end parallel
+end subroutine

>From af4fb7c5387c9d9b8b8628daf08bb9484341ebbf Mon Sep 17 00:00:00 2001
From: Leandro Lupori <leandro.lupori at linaro.org>
Date: Fri, 21 Aug 2026 12:13:14 -0300
Subject: [PATCH 2/3] Fix (most) regressions in the Fujitsu test suite

---
 flang/lib/Semantics/resolve-directives.cpp   | 21 +++++++++++++--
 flang/test/Semantics/OpenMP/default-none.f90 | 27 ++++++++++++++++++++
 2 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index e90acc144eb93..a70d6621c25aa 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -2744,12 +2744,29 @@ void OmpAttributeVisitor::CreateImplicitSymbols(
         }
         hasDefaultNoneError = true;
       };
+      Symbol *curSymbol{nullptr};
+      if (auto it{scope.find(symbol->name())}; it != scope.end()) {
+        curSymbol = &*it->second;
+      }
+      // Setting the DSA of a symbol with OmpNone DSA in the enclosing construct
+      // is allowed when:
+      // - The DSA is private (no read or write to the original variable).
+      // - The DSA is predetermined (should only private be allowed?).
+      // - The DSA is implicit. The standard seems to allow this only for
+      //   variables that are not referenced in the construct
+      //   (OpenMP 6.0 - 7.5.1 default Clause), but current implementation
+      //   allows the DSA to be implicitly set by a non-leaf directive.
+      // TODO Treat implied-DO variables in I/O lists as private.
       if (dsa.test(Symbol::Flag::OmpPrivate) ||
           crayPtrDSA.test(Symbol::Flag::OmpPrivate)) {
         checkDefaultNone = false;
-      } else if (dsa.any() || crayPtrDSA.any()) {
+      } else if ((dsa.any() && curSymbol &&
+                     curSymbol->test(Symbol::Flag::OmpExplicit)) ||
+          (crayPtrDSA.any() && crayPtr &&
+              crayPtr->test(Symbol::Flag::OmpExplicit))) {
         defaultNoneError(dirContext.directiveSource, symbol);
-      } else if (dirDepth == (int)dirContext_.size() - 1) {
+      } else if (dsa.none() && crayPtrDSA.none() &&
+          dirDepth == (int)dirContext_.size() - 1) {
         defaultNoneError(name.source, symbol);
       }
     }
diff --git a/flang/test/Semantics/OpenMP/default-none.f90 b/flang/test/Semantics/OpenMP/default-none.f90
index 0eb6e22ebd7ab..b713d314e5a6d 100644
--- a/flang/test/Semantics/OpenMP/default-none.f90
+++ b/flang/test/Semantics/OpenMP/default-none.f90
@@ -85,3 +85,30 @@ subroutine parallel_critical()
   !$omp end critical
   !$omp end parallel
 end subroutine
+
+subroutine implicit_predetermined()
+  !$omp parallel default(none)
+  !$omp parallel
+  !$omp do
+    do i = 0, 10
+    end do
+  !$omp end parallel
+  !$omp end parallel
+end subroutine
+
+subroutine implicit_explicit()
+  !$omp task default(none)
+  !$omp task
+  !$omp parallel private(i)
+  i = 1
+  !$omp end parallel
+  !$omp end task
+  !$omp end task
+end subroutine
+
+! TODO Treat implied-DO variables in I/O lists as private.
+subroutine implicit_do_in_io_list()
+  !$omp parallel !default(none)
+    write(6,*) (i,i=1,10)
+  !$omp end parallel
+end subroutine

>From ff5121ce7eda518d36f746c6f6debfe6f390c18c Mon Sep 17 00:00:00 2001
From: Leandro Lupori <leandro.lupori at linaro.org>
Date: Fri, 21 Aug 2026 14:20:57 -0300
Subject: [PATCH 3/3] Fix typo in subroutine name

---
 flang/test/Semantics/OpenMP/default-none.f90 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/flang/test/Semantics/OpenMP/default-none.f90 b/flang/test/Semantics/OpenMP/default-none.f90
index b713d314e5a6d..95c2d6ba4b689 100644
--- a/flang/test/Semantics/OpenMP/default-none.f90
+++ b/flang/test/Semantics/OpenMP/default-none.f90
@@ -107,7 +107,7 @@ subroutine implicit_explicit()
 end subroutine
 
 ! TODO Treat implied-DO variables in I/O lists as private.
-subroutine implicit_do_in_io_list()
+subroutine implied_do_in_io_list()
   !$omp parallel !default(none)
     write(6,*) (i,i=1,10)
   !$omp end parallel



More information about the flang-commits mailing list