[flang-commits] [flang] [flang][OpenMP] Fix the creation of implicit symbols for locals (PR #233600)
via flang-commits
flang-commits at lists.llvm.org
Mon Oct 19 14:50:17 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-openmp
Author: Leandro Lupori (luporl)
<details>
<summary>Changes</summary>
When creating implicit symbols for variables that are declared in a
nested scope (e.g. in a BLOCK), the constructs that enclose the symbol
declaration must be skipped, since the symbol doesn't exist in them.
Fixes #<!-- -->230273
Assisted-By: Claude Opus 5.5
---
Full diff: https://github.com/llvm/llvm-project/pull/233600.diff
3 Files Affected:
- (modified) flang/lib/Semantics/resolve-directives.cpp (+5)
- (modified) flang/test/Semantics/OpenMP/local-variables-3.f90 (+62)
- (added) flang/test/Semantics/OpenMP/local-variables-4.f90 (+87)
``````````diff
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index c5a23e1adda395..5e10b02e39480b 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -2673,6 +2673,11 @@ void OmpAttributeVisitor::CreateImplicitSymbols(
Symbol::Flags dsa;
Scope &scope{context_.FindScope(dirContext.directiveSource)};
+ // Skip constructs that enclose the symbol declaration (e.g. in a nested
+ // BLOCK).
+ if (IsLocalInsideScope(symbol->GetUltimate(), scope)) {
+ continue;
+ }
auto initSymbolDSA = [&](const Symbol *sym, Symbol::Flags &dsa) {
auto it{scope.find(sym->name())};
diff --git a/flang/test/Semantics/OpenMP/local-variables-3.f90 b/flang/test/Semantics/OpenMP/local-variables-3.f90
index 20d44c39da1079..d843955f10154d 100644
--- a/flang/test/Semantics/OpenMP/local-variables-3.f90
+++ b/flang/test/Semantics/OpenMP/local-variables-3.f90
@@ -121,3 +121,65 @@ subroutine block04()
!$omp end task
end block
end subroutine
+
+!CHECK-LABEL: !DEF: /block05 (Subroutine) Subprogram
+!CHECK: subroutine block05
+!CHECK: !$omp parallel default(private)
+!CHECK: block
+!CHECK: !DEF: /block05/OtherConstruct1/BlockConstruct1/cnt ObjectEntity INTEGER(4)
+!CHECK: integer cnt
+!CHECK: !REF: /block05/OtherConstruct1/BlockConstruct1/cnt
+!CHECK: cnt = 0
+!CHECK: !$omp single
+!CHECK: !REF: /block05/OtherConstruct1/BlockConstruct1/cnt
+!CHECK: cnt = cnt+1
+!CHECK: !$omp end single
+!CHECK: end block
+!CHECK: !$omp end parallel
+!CHECK: end subroutine
+
+subroutine block05()
+ !$omp parallel default(private)
+ block
+ integer :: cnt
+ cnt = 0
+ !$omp single
+ cnt = cnt + 1
+ !$omp end single
+ end block
+ !$omp end parallel
+end subroutine
+
+!CHECK-LABEL: !DEF: /block06 (Subroutine) Subprogram
+!CHECK: subroutine block06
+!CHECK: !$omp parallel default(private)
+!CHECK: block
+!CHECK: !DEF: /block06/OtherConstruct1/BlockConstruct1/auto ObjectEntity INTEGER(4)
+!CHECK: integer auto
+!CHECK: !DEF: /block06/OtherConstruct1/BlockConstruct1/s SAVE ObjectEntity INTEGER(4)
+!CHECK: integer, save :: s
+!CHECK: !REF: /block06/OtherConstruct1/BlockConstruct1/auto
+!CHECK: auto = 1
+!CHECK: !$omp task
+!CHECK: !DEF: /block06/OtherConstruct1/BlockConstruct1/OtherConstruct1/auto (OmpFirstPrivate, OmpImplicit) HostAssoc INTEGER(4)
+!CHECK: auto = 2
+!CHECK: !DEF: /block06/OtherConstruct1/BlockConstruct1/OtherConstruct1/s (OmpShared) HostAssoc INTEGER(4)
+!CHECK: s = 3
+!CHECK: !$omp end task
+!CHECK: end block
+!CHECK: !$omp end parallel
+!CHECK: end subroutine
+
+subroutine block06()
+ !$omp parallel default(private)
+ block
+ integer :: auto
+ integer, save :: s
+ auto = 1
+ !$omp task
+ auto = 2
+ s = 3
+ !$omp end task
+ end block
+ !$omp end parallel
+end subroutine
diff --git a/flang/test/Semantics/OpenMP/local-variables-4.f90 b/flang/test/Semantics/OpenMP/local-variables-4.f90
new file mode 100644
index 00000000000000..7a7653958f2310
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/local-variables-4.f90
@@ -0,0 +1,87 @@
+!RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp
+
+! A variable declared in a BLOCK inside an OpenMP construct has a predetermined
+! data-sharing attribute for that construct.
+
+subroutine s00
+ !$omp parallel default(none)
+ block
+ integer :: cnt
+ cnt = 0
+ !$omp single
+ cnt = cnt + 1
+ !$omp end single
+ end block
+ !$omp end parallel
+end
+
+subroutine s01
+ !$omp parallel default(none)
+ block
+ integer, save :: cnt
+ !$omp single
+ cnt = cnt + 1
+ !$omp end single
+ end block
+ !$omp end parallel
+end
+
+subroutine s02
+ !$omp parallel default(none)
+ block
+ integer :: v
+ v = 0
+ !$omp task firstprivate(v)
+ v = v + 1
+ !$omp end task
+ end block
+ !$omp end parallel
+end
+
+subroutine s03
+ integer :: x
+ !$omp parallel default(none)
+ block
+ !$omp single
+ !ERROR: The DEFAULT(NONE) clause requires that 'x' must be listed in a data-sharing attribute clause
+ x = 1
+ !$omp end single
+ end block
+ !$omp end parallel
+end
+
+subroutine s04
+ !$omp parallel default(none)
+ block
+ integer :: cnt
+ !$omp task default(none)
+ !ERROR: The DEFAULT(NONE) clause requires that 'cnt' must be listed in a data-sharing attribute clause
+ cnt = 1
+ !$omp end task
+ end block
+ !$omp end parallel
+end
+
+subroutine s05
+ !$omp parallel
+ block
+ integer :: v
+ !$omp single
+ v = 7
+ !$omp end single copyprivate(v)
+ print *, v
+ end block
+ !$omp end parallel
+end
+
+subroutine s06
+ !$omp parallel
+ block
+ integer, save :: s
+ !$omp single
+ s = 7
+ !ERROR: COPYPRIVATE variable 's' is not PRIVATE or THREADPRIVATE in outer context
+ !$omp end single copyprivate(s)
+ end block
+ !$omp end parallel
+end
``````````
</details>
https://github.com/llvm/llvm-project/pull/233600
More information about the flang-commits
mailing list