[flang-commits] [flang] [flang][OpenMP] Reject standalone block-associated variants (PR #213255)

via flang-commits flang-commits at lists.llvm.org
Sun Aug 2 22:27:58 PDT 2026


https://github.com/ssenthilnathan3 updated https://github.com/llvm/llvm-project/pull/213255

>From ff602bc7f23cc0177d32cb3e6b268d7de5e7d20c Mon Sep 17 00:00:00 2001
From: "ssenthil1490 at gmail.com" <ssenthil1490 at gmail.com>
Date: Fri, 31 Jul 2026 17:17:01 +0530
Subject: [PATCH 1/2] [flang][OpenMP] Reject standalone block-associated
 variants

---
 flang/lib/Semantics/check-omp-variant.cpp         | 15 +++++++++++++++
 .../Semantics/OpenMP/metadirective-common.f90     |  9 +++++++++
 .../Semantics/OpenMP/metadirective-loop-nest.f90  |  2 +-
 3 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/flang/lib/Semantics/check-omp-variant.cpp b/flang/lib/Semantics/check-omp-variant.cpp
index 0f8daf84d25ec..0bb799861ac33 100644
--- a/flang/lib/Semantics/check-omp-variant.cpp
+++ b/flang/lib/Semantics/check-omp-variant.cpp
@@ -716,8 +716,10 @@ void OmpStructureChecker::Enter(const parser::OmpDirectiveSpecification &x) {
   llvm::omp::Directive dirId{x.DirId()};
   bool checkDefaultNoneInAssociatedLoop{
       GetDirectiveNest(MetadirectiveNest) != 0};
+  bool isDelimited{false};
   if (const parser::OpenMPConstruct *meta{GetCurrentConstruct()}) {
     if (parser::Unwrap<parser::OmpDelimitedMetadirectiveDirective>(meta->u)) {
+      isDelimited = true;
       checkDefaultNoneInAssociatedLoop = false;
       unsigned version{context_.langOptions().OpenMPVersion};
       switch (llvm::omp::getDirectiveAssociation(dirId)) {
@@ -735,6 +737,19 @@ void OmpStructureChecker::Enter(const parser::OmpDirectiveSpecification &x) {
       }
     }
   }
+  if (!isDelimited && checkDefaultNoneInAssociatedLoop) {
+    OmpVariantMatchContext matchContext{context_};
+    if (currentWhenSelector_ &&
+        MayVariantBeSelected(currentWhenSelector_, context_, matchContext) &&
+        llvm::omp::getDirectiveAssociation(dirId) ==
+            llvm::omp::Association::Block) {
+      unsigned version{context_.langOptions().OpenMPVersion};
+      context_.Say(x.DirName().source,
+          "A standalone %s cannot contain a block-associated directive"_err_en_US,
+          parser::omp::GetUpperName(
+              llvm::omp::Directive::OMPD_metadirective, version));
+    }
+  }
 
   PushContextAndClauseSets(
       std::get<parser::OmpDirectiveName>(x.t).source, dirId);
diff --git a/flang/test/Semantics/OpenMP/metadirective-common.f90 b/flang/test/Semantics/OpenMP/metadirective-common.f90
index 3d219e9d9495a..04365b9d35195 100644
--- a/flang/test/Semantics/OpenMP/metadirective-common.f90
+++ b/flang/test/Semantics/OpenMP/metadirective-common.f90
@@ -45,3 +45,12 @@ subroutine f05
 !ERROR: 'context-selector' modifier is required
   !$omp & when(nothing)
 end
+
+! A standalone metadirective cannot contain a block-associated directive
+subroutine f06(x)
+  integer :: x
+  !$omp metadirective &
+!ERROR: A standalone METADIRECTIVE cannot contain a block-associated directive
+  !$omp & when(implementation={vendor(llvm)}: parallel num_threads(4)) otherwise(nothing)
+  x = 1
+end
diff --git a/flang/test/Semantics/OpenMP/metadirective-loop-nest.f90 b/flang/test/Semantics/OpenMP/metadirective-loop-nest.f90
index 9a19cbcc916a1..3982ee0f7cb9e 100644
--- a/flang/test/Semantics/OpenMP/metadirective-loop-nest.f90
+++ b/flang/test/Semantics/OpenMP/metadirective-loop-nest.f90
@@ -177,7 +177,7 @@ module no_loop_before_another_metadirective
   implicit none
   !ERROR: This construct should contain a DO-loop or a loop-nest-generating construct
   !$omp metadirective when(implementation={vendor(llvm)}: do) default(nothing)
-  !$omp metadirective when(implementation={vendor(llvm)}: parallel) default(nothing)
+  !$omp metadirective when(implementation={vendor(llvm)}: nothing) default(nothing)
 end module
 
 ! A loop in the enclosing subprogram cannot satisfy a variant from an

>From 5fdcee176d64c52fae4678d558453ef85755c39f Mon Sep 17 00:00:00 2001
From: "ssenthil1490 at gmail.com" <ssenthil1490 at gmail.com>
Date: Mon, 3 Aug 2026 10:57:40 +0530
Subject: [PATCH 2/2] fix: handled fallback variants and added regression test

---
 flang/lib/Semantics/check-omp-variant.cpp     | 20 +++++++++----------
 .../Parser/OpenMP/metadirective-dirspec.f90   |  6 +++---
 .../Semantics/OpenMP/metadirective-common.f90 | 10 ++++++++++
 3 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/flang/lib/Semantics/check-omp-variant.cpp b/flang/lib/Semantics/check-omp-variant.cpp
index 0bb799861ac33..c3f09b48cc19b 100644
--- a/flang/lib/Semantics/check-omp-variant.cpp
+++ b/flang/lib/Semantics/check-omp-variant.cpp
@@ -738,16 +738,16 @@ void OmpStructureChecker::Enter(const parser::OmpDirectiveSpecification &x) {
     }
   }
   if (!isDelimited && checkDefaultNoneInAssociatedLoop) {
-    OmpVariantMatchContext matchContext{context_};
-    if (currentWhenSelector_ &&
-        MayVariantBeSelected(currentWhenSelector_, context_, matchContext) &&
-        llvm::omp::getDirectiveAssociation(dirId) ==
-            llvm::omp::Association::Block) {
-      unsigned version{context_.langOptions().OpenMPVersion};
-      context_.Say(x.DirName().source,
-          "A standalone %s cannot contain a block-associated directive"_err_en_US,
-          parser::omp::GetUpperName(
-              llvm::omp::Directive::OMPD_metadirective, version));
+    if (llvm::omp::getDirectiveAssociation(dirId) ==
+        llvm::omp::Association::Block) {
+      OmpVariantMatchContext matchContext{context_};
+      if (MayVariantBeSelected(currentWhenSelector_, context_, matchContext)) {
+        unsigned version{context_.langOptions().OpenMPVersion};
+        context_.Say(x.DirName().source,
+            "A standalone %s cannot contain a block-associated directive"_err_en_US,
+            parser::omp::GetUpperName(
+                llvm::omp::Directive::OMPD_metadirective, version));
+      }
     }
   }
 
diff --git a/flang/test/Parser/OpenMP/metadirective-dirspec.f90 b/flang/test/Parser/OpenMP/metadirective-dirspec.f90
index d63db6c93cf40..7bfbeada97cc3 100644
--- a/flang/test/Parser/OpenMP/metadirective-dirspec.f90
+++ b/flang/test/Parser/OpenMP/metadirective-dirspec.f90
@@ -32,12 +32,12 @@ subroutine f00(x)
 subroutine f01(x)
   integer :: x
   !$omp metadirective when(user={condition(.true.)}: &
-  !$omp & critical(x))
+  !$omp & flush(x))
 end
 
 !UNPARSE: SUBROUTINE f01 (x)
 !UNPARSE:  INTEGER x
-!UNPARSE: !$OMP METADIRECTIVE WHEN(USER={CONDITION(.true._4)}: CRITICAL(x))
+!UNPARSE: !$OMP METADIRECTIVE WHEN(USER={CONDITION(.true._4)}: FLUSH(x))
 !UNPARSE: END SUBROUTINE
 
 !PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OmpMetadirectiveDirective
@@ -51,7 +51,7 @@ subroutine f01(x)
 !PARSE-TREE: | | | | | | LiteralConstant -> LogicalLiteralConstant
 !PARSE-TREE: | | | | | | | bool = 'true'
 !PARSE-TREE: | | OmpDirectiveSpecification
-!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = critical
+!PARSE-TREE: | | | OmpDirectiveName -> llvm::omp::Directive = flush
 !PARSE-TREE: | | | OmpArgumentList -> OmpArgument -> OmpObject -> Designator -> DataRef -> Name = 'x'
 !PARSE-TREE: | | | OmpClauseList ->
 
diff --git a/flang/test/Semantics/OpenMP/metadirective-common.f90 b/flang/test/Semantics/OpenMP/metadirective-common.f90
index 04365b9d35195..77678413351c0 100644
--- a/flang/test/Semantics/OpenMP/metadirective-common.f90
+++ b/flang/test/Semantics/OpenMP/metadirective-common.f90
@@ -54,3 +54,13 @@ subroutine f06(x)
   !$omp & when(implementation={vendor(llvm)}: parallel num_threads(4)) otherwise(nothing)
   x = 1
 end
+
+! The fallback (otherwise/default) variant is also checked
+subroutine f07(x)
+  integer :: x
+  !$omp metadirective &
+  !$omp & when(implementation={vendor(llvm)}: nothing) &
+!ERROR: A standalone METADIRECTIVE cannot contain a block-associated directive
+  !$omp & otherwise(parallel num_threads(4))
+  x = 1
+end



More information about the flang-commits mailing list