-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[flang][OpenMP] Semantic checks for GROUPPRIVATE #154779
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-flang-semantics @llvm/pr-subscribers-flang-openmp Author: Krzysztof Parzyszek (kparzysz) ChangesFull diff: https://github.com/llvm/llvm-project/pull/154779.diff 5 Files Affected:
diff --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h
index 5bde9f39ca0b0..f0e11ec3dc6e8 100644
--- a/flang/include/flang/Semantics/symbol.h
+++ b/flang/include/flang/Semantics/symbol.h
@@ -823,7 +823,7 @@ class Symbol {
OmpThreadprivate, OmpDeclareReduction, OmpFlushed, OmpCriticalLock,
OmpIfSpecified, OmpNone, OmpPreDetermined, OmpExplicit, OmpImplicit,
OmpDependObject, OmpInclusiveScan, OmpExclusiveScan, OmpInScanReduction,
- OmpUniform);
+ OmpUniform, OmpGroupPrivate);
using Flags = common::EnumSet<Flag, Flag_enumSize>;
const Scope &owner() const { return *owner_; }
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 92a2cfc330d35..142423b16334f 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1184,6 +1184,53 @@ void OmpStructureChecker::CheckThreadprivateOrDeclareTargetVar(
void OmpStructureChecker::Enter(const parser::OpenMPGroupprivate &x) {
PushContextAndClauseSets(
x.v.DirName().source, llvm::omp::Directive::OMPD_groupprivate);
+
+ for (const parser::OmpArgument &arg : x.v.Arguments().v) {
+ auto *locator{std::get_if<parser::OmpLocator>(&arg.u)};
+ const Symbol *sym{GetArgumentSymbol(arg)};
+
+ if (!locator || !sym ||
+ (!IsVariableListItem(*sym) && !IsCommonBlock(*sym))) {
+ context_.Say(arg.source,
+ "GROUPPRIVATE argument should be a variable or a named common block"_err_en_US);
+ continue;
+ }
+
+ if (sym->has<AssocEntityDetails>()) {
+ context_.SayWithDecl(*sym, arg.source,
+ "GROUPPRIVATE argument cannot be an an ASSOCIATE name"_err_en_US);
+ continue;
+ }
+ if (auto *obj{sym->detailsIf<ObjectEntityDetails>()}) {
+ if (obj->IsCoarray()) {
+ context_.Say(arg.source,
+ "GROUPPRIVATE argument cannot be an a coarray"_err_en_US);
+ continue;
+ }
+ if (obj->init()) {
+ context_.SayWithDecl(*sym, arg.source,
+ "GROUPPRIVATE argument cannot be declared with an initializer"_err_en_US);
+ continue;
+ }
+ }
+ if (sym->test(Symbol::Flag::InCommonBlock)) {
+ context_.Say(arg.source,
+ "GROUPPRIVATE argument cannot be an a member of a common block"_err_en_US);
+ continue;
+ }
+ if (!IsCommonBlock(*sym)) {
+ const Scope &thisScope{context_.FindScope(x.v.source)};
+ if (thisScope != sym->owner()) {
+ context_.SayWithDecl(*sym, arg.source,
+ "GROUPPRIVATE argument variable must be declared in the same scope as the construct on which it appears"_err_en_US);
+ continue;
+ } else if (!thisScope.IsModule() && !sym->attrs().test(Attr::SAVE)) {
+ context_.SayWithDecl(*sym, arg.source,
+ "GROUPPRIVATE argument variable must be declared in the module scope or have SAVE attribute"_err_en_US);
+ continue;
+ }
+ }
+ }
}
void OmpStructureChecker::Leave(const parser::OpenMPGroupprivate &x) {
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 6a4660c9882ab..96d95162beb73 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -391,6 +391,9 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
GetContext().withinConstruct = true;
}
+ bool Pre(const parser::OpenMPGroupprivate &);
+ void Post(const parser::OpenMPGroupprivate &) { PopContext(); }
+
bool Pre(const parser::OpenMPStandaloneConstruct &x) {
common::visit(
[&](auto &&s) {
@@ -842,7 +845,8 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
Symbol::Flags ompFlagsRequireMark{Symbol::Flag::OmpThreadprivate,
Symbol::Flag::OmpDeclareTarget, Symbol::Flag::OmpExclusiveScan,
- Symbol::Flag::OmpInclusiveScan, Symbol::Flag::OmpInScanReduction};
+ Symbol::Flag::OmpInclusiveScan, Symbol::Flag::OmpInScanReduction,
+ Symbol::Flag::OmpGroupPrivate};
Symbol::Flags dataCopyingAttributeFlags{
Symbol::Flag::OmpCopyIn, Symbol::Flag::OmpCopyPrivate};
@@ -2118,6 +2122,18 @@ void OmpAttributeVisitor::CheckAssocLoopLevel(
}
}
+bool OmpAttributeVisitor::Pre(const parser::OpenMPGroupprivate &x) {
+ PushContext(x.source, llvm::omp::Directive::OMPD_groupprivate);
+ for (const parser::OmpArgument &arg : x.v.Arguments().v) {
+ if (auto *locator{std::get_if<parser::OmpLocator>(&arg.u)}) {
+ if (auto *object{std::get_if<parser::OmpObject>(&locator->u)}) {
+ ResolveOmpObject(*object, Symbol::Flag::OmpGroupPrivate);
+ }
+ }
+ }
+ return true;
+}
+
bool OmpAttributeVisitor::Pre(const parser::OpenMPSectionsConstruct &x) {
const auto &beginSectionsDir{
std::get<parser::OmpBeginSectionsDirective>(x.t)};
diff --git a/flang/lib/Semantics/unparse-with-symbols.cpp b/flang/lib/Semantics/unparse-with-symbols.cpp
index 41077e0e0aad7..b199481131065 100644
--- a/flang/lib/Semantics/unparse-with-symbols.cpp
+++ b/flang/lib/Semantics/unparse-with-symbols.cpp
@@ -47,6 +47,11 @@ class SymbolDumpVisitor {
return true;
}
void Post(const parser::OmpClause &) { currStmt_ = std::nullopt; }
+ bool Pre(const parser::OpenMPGroupprivate &dir) {
+ currStmt_ = dir.source;
+ return true;
+ }
+ void Post(const parser::OpenMPGroupprivate &) { currStmt_ = std::nullopt; }
bool Pre(const parser::OpenMPThreadprivate &dir) {
currStmt_ = dir.source;
return true;
diff --git a/flang/test/Semantics/OpenMP/groupprivate.f90 b/flang/test/Semantics/OpenMP/groupprivate.f90
new file mode 100644
index 0000000000000..89afffd9dff65
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/groupprivate.f90
@@ -0,0 +1,47 @@
+!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=60
+
+module m00
+implicit none
+integer :: x = 1
+!ERROR: GROUPPRIVATE argument cannot be declared with an initializer
+!$omp groupprivate(x)
+!ERROR: GROUPPRIVATE argument should be a variable or a named common block
+!$omp groupprivate(f00)
+
+contains
+subroutine f00
+ implicit none
+ integer, save :: y
+ associate (z => y)
+ block
+ !ERROR: GROUPPRIVATE argument cannot be an an ASSOCIATE name
+ !$omp groupprivate(z)
+ end block
+ end associate
+end
+end module
+
+module m01
+implicit none
+integer :: x, y
+common /some_block/ x
+!ERROR: GROUPPRIVATE argument cannot be an a member of a common block
+!$omp groupprivate(x)
+
+contains
+subroutine f01
+ implicit none
+ integer :: z
+ !ERROR: GROUPPRIVATE argument variable must be declared in the same scope as the construct on which it appears
+ !$omp groupprivate(y)
+ !ERROR: GROUPPRIVATE argument variable must be declared in the module scope or have SAVE attribute
+ !$omp groupprivate(z)
+end
+end module
+
+module m02
+implicit none
+integer :: x(10)[*]
+!ERROR: GROUPPRIVATE argument cannot be an a coarray
+!$omp groupprivate(x)
+end module
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@@ -823,7 +823,7 @@ class Symbol { | |||
OmpThreadprivate, OmpDeclareReduction, OmpFlushed, OmpCriticalLock, | |||
OmpIfSpecified, OmpNone, OmpPreDetermined, OmpExplicit, OmpImplicit, | |||
OmpDependObject, OmpInclusiveScan, OmpExclusiveScan, OmpInScanReduction, | |||
OmpUniform); | |||
OmpUniform, OmpGroupPrivate); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Maybe move this to the data-sharing attribute clauses, as it's sort is a DSA.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
No description provided.