[flang][OpenMP] Semantic checks for GROUPPRIVATE by kparzysz · Pull Request #154779 · llvm/llvm-project (original) (raw)
@llvm/pr-subscribers-flang-semantics
@llvm/pr-subscribers-flang-openmp
Author: Krzysztof Parzyszek (kparzysz)
Changes
Full diff: https://github.com/llvm/llvm-project/pull/154779.diff
5 Files Affected:
- (modified) flang/include/flang/Semantics/symbol.h (+1-1)
- (modified) flang/lib/Semantics/check-omp-structure.cpp (+47)
- (modified) flang/lib/Semantics/resolve-directives.cpp (+17-1)
- (modified) flang/lib/Semantics/unparse-with-symbols.cpp (+5)
- (added) flang/test/Semantics/OpenMP/groupprivate.f90 (+47)
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_ifparser::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()) {
context_.SayWithDecl(*sym, arg.source,"GROUPPRIVATE argument cannot be an an ASSOCIATE name"_err_en_US);continue;- }
- if (auto *obj{sym->detailsIf()}) {
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 : DirectiveAttributeVisitorllvm::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 : DirectiveAttributeVisitorllvm::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::Flags dataCopyingAttributeFlags{ Symbol::Flag::OmpCopyIn, Symbol::Flag::OmpCopyPrivate};Symbol::Flag::OmpGroupPrivate};
@@ -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_ifparser::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::getparser::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