Skip to content

Commit eebd6c6

Browse files
Fix Copyprivate clause semantics check
Changes: - Throw error for repeated list items in the copyprivate clause - Throw warnings for repeated use of copyprivate and nowait in the end directive
1 parent 6cbaf66 commit eebd6c6

File tree

3 files changed

+59
-21
lines changed

3 files changed

+59
-21
lines changed

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

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,33 +1204,71 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
12041204
}
12051205

12061206
if (GetContext().directive == llvm::omp::Directive::OMPD_single) {
1207-
bool foundCopyPrivate{false};
1208-
bool foundNowait{false};
1209-
parser::CharBlock NowaitSource{""};
1210-
auto catchCopyPrivateNowaitClauses = [&](const auto &dir) {
1207+
std::set<Symbol *> singleCopyprivateSyms;
1208+
std::set<Symbol *> endSingleCopyprivateSyms;
1209+
bool singleNowait{false};
1210+
bool endSingleNowait{false};
1211+
parser::CharBlock NowaitSource;
1212+
1213+
auto catchCopyPrivateNowaitClauses = [&](const auto &dir, bool endDir) {
12111214
for (auto &clause : std::get<parser::OmpClauseList>(dir.t).v) {
12121215
if (clause.Id() == llvm::omp::Clause::OMPC_copyprivate) {
1213-
if (foundCopyPrivate) {
1214-
context_.Say(clause.source,
1215-
"At most one COPYPRIVATE clause can appear on the SINGLE directive"_err_en_US);
1216-
} else {
1217-
foundCopyPrivate = true;
1216+
for (const auto &ompObject : GetOmpObjectList(clause)->v) {
1217+
const auto *name{parser::Unwrap<parser::Name>(ompObject)};
1218+
if (Symbol * symbol{name->symbol}) {
1219+
if (singleCopyprivateSyms.count(symbol)) {
1220+
if (endDir) {
1221+
context_.Warn(common::UsageWarning::OpenMPUsage, name->source,
1222+
"The COPYPRIVATE clause with '%s' is already used on the SINGLE directive"_warn_en_US,
1223+
name->ToString());
1224+
} else {
1225+
context_.Say(name->source,
1226+
"'%s' appears in more than one COPYPRIVATE clause on the SINGLE directive"_err_en_US,
1227+
name->ToString());
1228+
}
1229+
} else if (endSingleCopyprivateSyms.count(symbol)) {
1230+
context_.Say(name->source,
1231+
"'%s' appears in more than one COPYPRIVATE clause on the END SINGLE directive"_err_en_US,
1232+
name->ToString());
1233+
} else {
1234+
if (endDir) {
1235+
endSingleCopyprivateSyms.insert(symbol);
1236+
} else {
1237+
singleCopyprivateSyms.insert(symbol);
1238+
}
1239+
}
1240+
}
12181241
}
12191242
} else if (clause.Id() == llvm::omp::Clause::OMPC_nowait) {
1220-
if (foundNowait) {
1243+
if (singleNowait) {
1244+
if (endDir) {
1245+
context_.Warn(common::UsageWarning::OpenMPUsage, clause.source,
1246+
"NOWAIT clause is already used on the SINGLE directive"_warn_en_US);
1247+
} else {
1248+
context_.Say(clause.source,
1249+
"At most one NOWAIT clause can appear on the SINGLE directive"_err_en_US);
1250+
}
1251+
} else if (endSingleNowait) {
12211252
context_.Say(clause.source,
1222-
"At most one NOWAIT clause can appear on the SINGLE directive"_err_en_US);
1253+
"At most one NOWAIT clause can appear on the END SINGLE directive"_err_en_US);
12231254
} else {
1224-
foundNowait = true;
1255+
if (endDir) {
1256+
endSingleNowait = true;
1257+
} else {
1258+
singleNowait = true;
1259+
}
1260+
}
1261+
if (!NowaitSource.ToString().size()) {
12251262
NowaitSource = clause.source;
12261263
}
12271264
}
12281265
}
12291266
};
1230-
catchCopyPrivateNowaitClauses(beginBlockDir);
1231-
catchCopyPrivateNowaitClauses(endBlockDir);
1267+
catchCopyPrivateNowaitClauses(beginBlockDir, false);
1268+
catchCopyPrivateNowaitClauses(endBlockDir, true);
12321269
unsigned version{context_.langOptions().OpenMPVersion};
1233-
if (version <= 52 && foundCopyPrivate && foundNowait) {
1270+
if (version <= 52 && NowaitSource.ToString().size() &&
1271+
(singleCopyprivateSyms.size() || endSingleCopyprivateSyms.size())) {
12341272
context_.Say(NowaitSource,
12351273
"NOWAIT clause must not be used with COPYPRIVATE clause on the SINGLE directive"_err_en_US);
12361274
}
@@ -1818,8 +1856,8 @@ void OmpStructureChecker::Enter(const parser::OpenMPDispatchConstruct &x) {
18181856

18191857
auto it{block.begin()};
18201858
bool passChecks{false};
1821-
if (const parser::AssignmentStmt *
1822-
assignStmt{parser::Unwrap<parser::AssignmentStmt>(*it)}) {
1859+
if (const parser::AssignmentStmt *assignStmt{
1860+
parser::Unwrap<parser::AssignmentStmt>(*it)}) {
18231861
if (parser::Unwrap<parser::FunctionReference>(assignStmt->t)) {
18241862
passChecks = true;
18251863
}

flang/test/Semantics/OpenMP/clause-validity01.f90

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -334,8 +334,8 @@
334334
!$omp single private(a) lastprivate(c) nowait
335335
a = 3.14
336336
!ERROR: COPYPRIVATE variable 'a' may not appear on a PRIVATE or FIRSTPRIVATE clause on a SINGLE construct
337-
!ERROR: At most one NOWAIT clause can appear on the SINGLE directive
338-
!ERROR: At most one NOWAIT clause can appear on the SINGLE directive
337+
!WARNING: NOWAIT clause is already used on the SINGLE directive
338+
!WARNING: NOWAIT clause is already used on the SINGLE directive
339339
!ERROR: At most one NOWAIT clause can appear on the END SINGLE directive
340340
!$omp end single copyprivate(a) nowait nowait
341341
c = 2

flang/test/Semantics/OpenMP/single03.f90

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,13 @@ subroutine omp_single
3838
!ERROR: COPYPRIVATE variable 'j' may not appear on a PRIVATE or FIRSTPRIVATE clause on a SINGLE construct
3939
!$omp single private(j) copyprivate(j)
4040
print *, "omp single", j
41-
!ERROR: At most one COPYPRIVATE clause can appear on the SINGLE directive
4241
!ERROR: COPYPRIVATE variable 'j' may not appear on a PRIVATE or FIRSTPRIVATE clause on a SINGLE construct
42+
!WARNING: The COPYPRIVATE clause with 'j' is already used on the SINGLE directive
4343
!$omp end single copyprivate(j)
4444

4545
!$omp single nowait
4646
print *, "omp single", j
47-
!ERROR: At most one NOWAIT clause can appear on the SINGLE directive
47+
!WARNING: NOWAIT clause is already used on the SINGLE directive
4848
!$omp end single nowait
4949
!$omp end parallel
5050

0 commit comments

Comments
 (0)