[flang-commits] [flang] [flang][OpenMP] Allow common blocks in nested directives (PR #88430)

Leandro Lupori via flang-commits flang-commits at lists.llvm.org
Thu Apr 11 12:47:02 PDT 2024


https://github.com/luporl created https://github.com/llvm/llvm-project/pull/88430

COMMON block names must be declared in the same scoping unit in
which the OpenMP directive or clause appears. However, given that
common blocks and threadprivate directives can't be nested inside
other directives, such as parallel, and based on the behavior of
other compilers, it seems that OpenMP block constructs should not
be considered as scoping units.

This patch implements this behavior by also looking for common
block names in the scoping unit of the outermost directive.


>From d4630a369953a28e12fb66be2b70158b290d2477 Mon Sep 17 00:00:00 2001
From: Leandro Lupori <leandro.lupori at linaro.org>
Date: Thu, 11 Apr 2024 16:33:39 -0300
Subject: [PATCH] [flang][OpenMP] Allow common blocks in nested directives

COMMON block names must be declared in the same scoping unit in
which the OpenMP directive or clause appears. However, given that
common blocks and threadprivate directives can't be nested inside
other directives, such as parallel, and based on the behavior of
other compilers, it seems that OpenMP block constructs should not
be considered as scoping units.

This patch implements this behavior by also looking for common
block names in the scoping unit of the outermost directive.
---
 flang/lib/Semantics/resolve-directives.cpp | 17 +++++++++++++----
 flang/test/Semantics/OpenMP/resolve03.f90  | 16 ++++++++++++++++
 2 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 27af192f606be9..ac1c988e174275 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -2096,10 +2096,19 @@ Symbol *OmpAttributeVisitor::ResolveOmpCommonBlockName(
     name->symbol = cur;
     return cur;
   }
-  // Then check parent scope
-  if (auto *prev{GetContext().scope.parent().FindCommonBlock(name->source)}) {
-    name->symbol = prev;
-    return prev;
+  // Then check parent scope, skipping OpenMP scopes and making sure
+  // that the top directive started its own scope.
+  DirContext &topDirContext = dirContext_.front();
+  Scope &topDirScope = topDirContext.scope;
+  assert(!topDirContext.directiveSource.empty());
+  assert(!topDirScope.sourceRange().empty());
+  if (!topDirScope.IsTopLevel() &&
+      topDirContext.directiveSource.begin() ==
+          topDirScope.sourceRange().begin()) {
+    if (auto *prev{topDirScope.parent().FindCommonBlock(name->source)}) {
+      name->symbol = prev;
+      return prev;
+    }
   }
   return nullptr;
 }
diff --git a/flang/test/Semantics/OpenMP/resolve03.f90 b/flang/test/Semantics/OpenMP/resolve03.f90
index b9306c4fe9cb4d..1228f070e0595f 100644
--- a/flang/test/Semantics/OpenMP/resolve03.f90
+++ b/flang/test/Semantics/OpenMP/resolve03.f90
@@ -8,6 +8,9 @@
 
   common /c/ a, b
   integer a(3), b
+  common /tc/ xy
+  integer xz
+  !$omp threadprivate(/tc/)
 
   A = 1
   B = 2
@@ -19,4 +22,17 @@
     !$omp end parallel
   end block
   print *, a, b
+
+  ! Common block names may be used inside nested OpenMP directives.
+  !$omp parallel
+    !$omp parallel copyin(/tc/)
+      xz = xz + 10
+    !$omp end parallel
+  !$omp end parallel
+
+  !$omp parallel
+    !$omp single
+      xz = 18
+    !$omp end single copyprivate(/tc/)
+  !$omp end parallel
 end



More information about the flang-commits mailing list