@@ -1204,33 +1204,71 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
1204
1204
}
1205
1205
1206
1206
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) {
1211
1214
for (auto &clause : std::get<parser::OmpClauseList>(dir.t ).v ) {
1212
1215
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
+ }
1218
1241
}
1219
1242
} 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) {
1221
1252
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);
1223
1254
} else {
1224
- foundNowait = true ;
1255
+ if (endDir) {
1256
+ endSingleNowait = true ;
1257
+ } else {
1258
+ singleNowait = true ;
1259
+ }
1260
+ }
1261
+ if (!NowaitSource.ToString ().size ()) {
1225
1262
NowaitSource = clause.source ;
1226
1263
}
1227
1264
}
1228
1265
}
1229
1266
};
1230
- catchCopyPrivateNowaitClauses (beginBlockDir);
1231
- catchCopyPrivateNowaitClauses (endBlockDir);
1267
+ catchCopyPrivateNowaitClauses (beginBlockDir, false );
1268
+ catchCopyPrivateNowaitClauses (endBlockDir, true );
1232
1269
unsigned version{context_.langOptions ().OpenMPVersion };
1233
- if (version <= 52 && foundCopyPrivate && foundNowait) {
1270
+ if (version <= 52 && NowaitSource.ToString ().size () &&
1271
+ (singleCopyprivateSyms.size () || endSingleCopyprivateSyms.size ())) {
1234
1272
context_.Say (NowaitSource,
1235
1273
" NOWAIT clause must not be used with COPYPRIVATE clause on the SINGLE directive" _err_en_US);
1236
1274
}
@@ -1818,8 +1856,8 @@ void OmpStructureChecker::Enter(const parser::OpenMPDispatchConstruct &x) {
1818
1856
1819
1857
auto it{block.begin ()};
1820
1858
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)}) {
1823
1861
if (parser::Unwrap<parser::FunctionReference>(assignStmt->t )) {
1824
1862
passChecks = true ;
1825
1863
}
0 commit comments