Skip to content

Commit 3768ec3

Browse files
authored
[flang][OpenMP] Semantic checks for GROUPPRIVATE (#154779)
1 parent 2a83cf5 commit 3768ec3

File tree

5 files changed

+117
-1
lines changed

5 files changed

+117
-1
lines changed

flang/include/flang/Semantics/symbol.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -811,6 +811,7 @@ class Symbol {
811811
AccCommonBlock, AccThreadPrivate, AccReduction, AccNone, AccPreDetermined,
812812
// OpenMP data-sharing attribute
813813
OmpShared, OmpPrivate, OmpLinear, OmpFirstPrivate, OmpLastPrivate,
814+
OmpGroupPrivate,
814815
// OpenMP data-mapping attribute
815816
OmpMapTo, OmpMapFrom, OmpMapToFrom, OmpMapStorage, OmpMapDelete,
816817
OmpUseDevicePtr, OmpUseDeviceAddr, OmpIsDevicePtr, OmpHasDeviceAddr,

flang/lib/Semantics/check-omp-structure.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1184,6 +1184,53 @@ void OmpStructureChecker::CheckThreadprivateOrDeclareTargetVar(
11841184
void OmpStructureChecker::Enter(const parser::OpenMPGroupprivate &x) {
11851185
PushContextAndClauseSets(
11861186
x.v.DirName().source, llvm::omp::Directive::OMPD_groupprivate);
1187+
1188+
for (const parser::OmpArgument &arg : x.v.Arguments().v) {
1189+
auto *locator{std::get_if<parser::OmpLocator>(&arg.u)};
1190+
const Symbol *sym{GetArgumentSymbol(arg)};
1191+
1192+
if (!locator || !sym ||
1193+
(!IsVariableListItem(*sym) && !IsCommonBlock(*sym))) {
1194+
context_.Say(arg.source,
1195+
"GROUPPRIVATE argument should be a variable or a named common block"_err_en_US);
1196+
continue;
1197+
}
1198+
1199+
if (sym->has<AssocEntityDetails>()) {
1200+
context_.SayWithDecl(*sym, arg.source,
1201+
"GROUPPRIVATE argument cannot be an an ASSOCIATE name"_err_en_US);
1202+
continue;
1203+
}
1204+
if (auto *obj{sym->detailsIf<ObjectEntityDetails>()}) {
1205+
if (obj->IsCoarray()) {
1206+
context_.Say(arg.source,
1207+
"GROUPPRIVATE argument cannot be an a coarray"_err_en_US);
1208+
continue;
1209+
}
1210+
if (obj->init()) {
1211+
context_.SayWithDecl(*sym, arg.source,
1212+
"GROUPPRIVATE argument cannot be declared with an initializer"_err_en_US);
1213+
continue;
1214+
}
1215+
}
1216+
if (sym->test(Symbol::Flag::InCommonBlock)) {
1217+
context_.Say(arg.source,
1218+
"GROUPPRIVATE argument cannot be an a member of a common block"_err_en_US);
1219+
continue;
1220+
}
1221+
if (!IsCommonBlock(*sym)) {
1222+
const Scope &thisScope{context_.FindScope(x.v.source)};
1223+
if (thisScope != sym->owner()) {
1224+
context_.SayWithDecl(*sym, arg.source,
1225+
"GROUPPRIVATE argument variable must be declared in the same scope as the construct on which it appears"_err_en_US);
1226+
continue;
1227+
} else if (!thisScope.IsModule() && !sym->attrs().test(Attr::SAVE)) {
1228+
context_.SayWithDecl(*sym, arg.source,
1229+
"GROUPPRIVATE argument variable must be declared in the module scope or have SAVE attribute"_err_en_US);
1230+
continue;
1231+
}
1232+
}
1233+
}
11871234
}
11881235

11891236
void OmpStructureChecker::Leave(const parser::OpenMPGroupprivate &x) {

flang/lib/Semantics/resolve-directives.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,9 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
391391
GetContext().withinConstruct = true;
392392
}
393393

394+
bool Pre(const parser::OpenMPGroupprivate &);
395+
void Post(const parser::OpenMPGroupprivate &) { PopContext(); }
396+
394397
bool Pre(const parser::OpenMPStandaloneConstruct &x) {
395398
common::visit(
396399
[&](auto &&s) {
@@ -842,7 +845,8 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
842845

843846
Symbol::Flags ompFlagsRequireMark{Symbol::Flag::OmpThreadprivate,
844847
Symbol::Flag::OmpDeclareTarget, Symbol::Flag::OmpExclusiveScan,
845-
Symbol::Flag::OmpInclusiveScan, Symbol::Flag::OmpInScanReduction};
848+
Symbol::Flag::OmpInclusiveScan, Symbol::Flag::OmpInScanReduction,
849+
Symbol::Flag::OmpGroupPrivate};
846850

847851
Symbol::Flags dataCopyingAttributeFlags{
848852
Symbol::Flag::OmpCopyIn, Symbol::Flag::OmpCopyPrivate};
@@ -2118,6 +2122,18 @@ void OmpAttributeVisitor::CheckAssocLoopLevel(
21182122
}
21192123
}
21202124

2125+
bool OmpAttributeVisitor::Pre(const parser::OpenMPGroupprivate &x) {
2126+
PushContext(x.source, llvm::omp::Directive::OMPD_groupprivate);
2127+
for (const parser::OmpArgument &arg : x.v.Arguments().v) {
2128+
if (auto *locator{std::get_if<parser::OmpLocator>(&arg.u)}) {
2129+
if (auto *object{std::get_if<parser::OmpObject>(&locator->u)}) {
2130+
ResolveOmpObject(*object, Symbol::Flag::OmpGroupPrivate);
2131+
}
2132+
}
2133+
}
2134+
return true;
2135+
}
2136+
21212137
bool OmpAttributeVisitor::Pre(const parser::OpenMPSectionsConstruct &x) {
21222138
const auto &beginSectionsDir{
21232139
std::get<parser::OmpBeginSectionsDirective>(x.t)};

flang/lib/Semantics/unparse-with-symbols.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ class SymbolDumpVisitor {
4747
return true;
4848
}
4949
void Post(const parser::OmpClause &) { currStmt_ = std::nullopt; }
50+
bool Pre(const parser::OpenMPGroupprivate &dir) {
51+
currStmt_ = dir.source;
52+
return true;
53+
}
54+
void Post(const parser::OpenMPGroupprivate &) { currStmt_ = std::nullopt; }
5055
bool Pre(const parser::OpenMPThreadprivate &dir) {
5156
currStmt_ = dir.source;
5257
return true;
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=60
2+
3+
module m00
4+
implicit none
5+
integer :: x = 1
6+
!ERROR: GROUPPRIVATE argument cannot be declared with an initializer
7+
!$omp groupprivate(x)
8+
!ERROR: GROUPPRIVATE argument should be a variable or a named common block
9+
!$omp groupprivate(f00)
10+
11+
contains
12+
subroutine f00
13+
implicit none
14+
integer, save :: y
15+
associate (z => y)
16+
block
17+
!ERROR: GROUPPRIVATE argument cannot be an an ASSOCIATE name
18+
!$omp groupprivate(z)
19+
end block
20+
end associate
21+
end
22+
end module
23+
24+
module m01
25+
implicit none
26+
integer :: x, y
27+
common /some_block/ x
28+
!ERROR: GROUPPRIVATE argument cannot be an a member of a common block
29+
!$omp groupprivate(x)
30+
31+
contains
32+
subroutine f01
33+
implicit none
34+
integer :: z
35+
!ERROR: GROUPPRIVATE argument variable must be declared in the same scope as the construct on which it appears
36+
!$omp groupprivate(y)
37+
!ERROR: GROUPPRIVATE argument variable must be declared in the module scope or have SAVE attribute
38+
!$omp groupprivate(z)
39+
end
40+
end module
41+
42+
module m02
43+
implicit none
44+
integer :: x(10)[*]
45+
!ERROR: GROUPPRIVATE argument cannot be an a coarray
46+
!$omp groupprivate(x)
47+
end module

0 commit comments

Comments
 (0)