[flang-commits] [flang] [flang][OpenMP] Don't allow namelist variables with threadprivate (PR #130957)
Tom Eccles via flang-commits
flang-commits at lists.llvm.org
Tue Mar 18 10:49:34 PDT 2025
https://github.com/tblah updated https://github.com/llvm/llvm-project/pull/130957
>From 0800f124ee4e2cc8a71bc2f325c5ccf341d6c15e Mon Sep 17 00:00:00 2001
From: Tom Eccles <tom.eccles at arm.com>
Date: Wed, 12 Mar 2025 13:01:59 +0000
Subject: [PATCH 1/2] [flang][OpenMP] Don't allow namelist variables with
threadprivate
While the standard doesn't explicitly mention namelist variables in this
case, it does prohibit privatization of namelist variables. Flang
decided to also prohibit namelist variables from appearing in a
reduction clause.
Variables that are part of a namelist are linked to I/O mechanisms, and
their memory association and initialization are managed by the compiler
in a way that conflicts with the requirements of threadprivate
variables. I propose we should add this restriction.
---
flang/lib/Semantics/check-omp-structure.cpp | 9 +++++++++
flang/test/Semantics/OpenMP/threadprivate09.f90 | 12 ++++++++++++
2 files changed, 21 insertions(+)
create mode 100644 flang/test/Semantics/OpenMP/threadprivate09.f90
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 5fcebdca0bc5f..e98c9c3091cb4 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1516,6 +1516,10 @@ void OmpStructureChecker::CheckThreadprivateOrDeclareTargetVar(
"A variable in a %s directive cannot appear in an "
"EQUIVALENCE statement"_err_en_US,
ContextDirectiveAsFortran());
+ } else if (name->symbol->test(Symbol::Flag::InNamelist)) {
+ context_.Say(name->source,
+ "A variable in a %s directive cannot appear in a NAMELIST"_err_en_US,
+ ContextDirectiveAsFortran());
} else if (name->symbol->test(Symbol::Flag::OmpThreadprivate) &&
GetContext().directive ==
llvm::omp::Directive::OMPD_declare_target) {
@@ -1571,6 +1575,11 @@ void OmpStructureChecker::CheckThreadprivateOrDeclareTargetVar(
ContextDirectiveAsFortran(), obj->name(),
name.symbol->name());
}
+ if (obj->test(Symbol::Flag::InNamelist)) {
+ context_.Say(name.source,
+ "A variable in a %s directive cannot appear in a NAMELIST"_err_en_US,
+ ContextDirectiveAsFortran());
+ }
}
}
}
diff --git a/flang/test/Semantics/OpenMP/threadprivate09.f90 b/flang/test/Semantics/OpenMP/threadprivate09.f90
new file mode 100644
index 0000000000000..02236d19d9d01
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/threadprivate09.f90
@@ -0,0 +1,12 @@
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+
+! Check that namelist variables cannot be used with threadprivate
+
+module m
+ integer :: nam1
+ common /com1/nam1
+ namelist /nam/nam1
+
+ !ERROR: A variable in a THREADPRIVATE directive cannot appear in a NAMELIST
+ !$omp threadprivate(/com1/)
+end
>From 42438c575de89091007019e496a893c3969077c6 Mon Sep 17 00:00:00 2001
From: Tom Eccles <tom.eccles at arm.com>
Date: Tue, 18 Mar 2025 17:48:23 +0000
Subject: [PATCH 2/2] Restrict to only the threadprivate directive
---
flang/lib/Semantics/check-omp-structure.cpp | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index e98c9c3091cb4..10e353a500813 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1516,7 +1516,9 @@ void OmpStructureChecker::CheckThreadprivateOrDeclareTargetVar(
"A variable in a %s directive cannot appear in an "
"EQUIVALENCE statement"_err_en_US,
ContextDirectiveAsFortran());
- } else if (name->symbol->test(Symbol::Flag::InNamelist)) {
+ } else if (name->symbol->test(Symbol::Flag::InNamelist) &&
+ GetContext().directive ==
+ llvm::omp::Directive::OMPD_threadprivate) {
context_.Say(name->source,
"A variable in a %s directive cannot appear in a NAMELIST"_err_en_US,
ContextDirectiveAsFortran());
@@ -1575,7 +1577,9 @@ void OmpStructureChecker::CheckThreadprivateOrDeclareTargetVar(
ContextDirectiveAsFortran(), obj->name(),
name.symbol->name());
}
- if (obj->test(Symbol::Flag::InNamelist)) {
+ if (obj->test(Symbol::Flag::InNamelist) &&
+ GetContext().directive ==
+ llvm::omp::OMPD_threadprivate) {
context_.Say(name.source,
"A variable in a %s directive cannot appear in a NAMELIST"_err_en_US,
ContextDirectiveAsFortran());
More information about the flang-commits
mailing list