@@ -3333,14 +3333,17 @@ void OmpStructureChecker::Leave(const parser::OmpAtomicRead &) {
33333333 CheckNotAllowedIfClause (llvm::omp::Clause::OMPC_read,
33343334 {llvm::omp::Clause::OMPC_release, llvm::omp::Clause::OMPC_acq_rel});
33353335}
3336+
33363337void OmpStructureChecker::Leave (const parser::OmpAtomicWrite &) {
33373338 CheckNotAllowedIfClause (llvm::omp::Clause::OMPC_write,
33383339 {llvm::omp::Clause::OMPC_acquire, llvm::omp::Clause::OMPC_acq_rel});
33393340}
3341+
33403342void OmpStructureChecker::Leave (const parser::OmpAtomicUpdate &) {
33413343 CheckNotAllowedIfClause (llvm::omp::Clause::OMPC_update,
33423344 {llvm::omp::Clause::OMPC_acquire, llvm::omp::Clause::OMPC_acq_rel});
33433345}
3346+
33443347// OmpAtomic node represents atomic directive without atomic-clause.
33453348// atomic-clause - READ,WRITE,UPDATE,CAPTURE.
33463349void OmpStructureChecker::Leave (const parser::OmpAtomic &) {
@@ -3353,6 +3356,7 @@ void OmpStructureChecker::Leave(const parser::OmpAtomic &) {
33533356 " Clause ACQ_REL is not allowed on the ATOMIC directive" _err_en_US);
33543357 }
33553358}
3359+
33563360// Restrictions specific to each clause are implemented apart from the
33573361// generalized restrictions.
33583362void OmpStructureChecker::Enter (const parser::OmpClause::Aligned &x) {
@@ -3364,15 +3368,48 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Aligned &x) {
33643368 }
33653369 // 2.8.1 TODO: list-item attribute check
33663370}
3371+
33673372void OmpStructureChecker::Enter (const parser::OmpClause::Defaultmap &x) {
33683373 CheckAllowedClause (llvm::omp::Clause::OMPC_defaultmap);
3374+ unsigned version{context_.langOptions ().OpenMPVersion };
3375+ using ImplicitBehavior = parser::OmpDefaultmapClause::ImplicitBehavior;
3376+ auto behavior{std::get<ImplicitBehavior>(x.v .t )};
3377+ if (version <= 45 ) {
3378+ if (behavior != ImplicitBehavior::Tofrom) {
3379+ context_.Say (GetContext ().clauseSource ,
3380+ " %s is not allowed in %s, %s" _warn_en_US,
3381+ parser::ToUpperCaseLetters (
3382+ parser::OmpDefaultmapClause::EnumToString (behavior)),
3383+ ThisVersion (version), TryVersion (50 ));
3384+ }
3385+ }
33693386 using VariableCategory = parser::OmpDefaultmapClause::VariableCategory;
3370- if (!std::get<std::optional<VariableCategory>>(x.v .t )) {
3371- context_.Say (GetContext ().clauseSource ,
3372- " The argument TOFROM:SCALAR must be specified on the DEFAULTMAP "
3373- " clause" _err_en_US);
3387+ auto maybeCategory{std::get<std::optional<VariableCategory>>(x.v .t )};
3388+ if (!maybeCategory) {
3389+ if (version <= 45 ) {
3390+ context_.Say (GetContext ().clauseSource ,
3391+ " The DEFAULTMAP clause requires a variable-category SCALAR in %s, %s" _warn_en_US,
3392+ ThisVersion (version), TryVersion (50 ));
3393+ }
3394+ } else {
3395+ VariableCategory category{*maybeCategory};
3396+ unsigned tryVersion{0 };
3397+ if (version <= 45 && category != VariableCategory::Scalar) {
3398+ tryVersion = 50 ;
3399+ }
3400+ if (version < 52 && category == VariableCategory::All) {
3401+ tryVersion = 52 ;
3402+ }
3403+ if (tryVersion) {
3404+ context_.Say (GetContext ().clauseSource ,
3405+ " %s is not allowed in %s, %s" _warn_en_US,
3406+ parser::ToUpperCaseLetters (
3407+ parser::OmpDefaultmapClause::EnumToString (category)),
3408+ ThisVersion (version), TryVersion (tryVersion));
3409+ }
33743410 }
33753411}
3412+
33763413void OmpStructureChecker::Enter (const parser::OmpClause::If &x) {
33773414 CheckAllowedClause (llvm::omp::Clause::OMPC_if);
33783415 using dirNameModifier = parser::OmpIfClause::DirectiveNameModifier;
0 commit comments