@@ -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 }
0 commit comments