diff --git a/flang/lib/Semantics/check-acc-structure.cpp b/flang/lib/Semantics/check-acc-structure.cpp index 8adb15e9bc5c..4559050e6935 100644 --- a/flang/lib/Semantics/check-acc-structure.cpp +++ b/flang/lib/Semantics/check-acc-structure.cpp @@ -121,6 +121,19 @@ private: llvm::acc::Directive currentDirective_; }; +bool AccStructureChecker::CheckAllowedModifier(llvm::acc::Clause clause) { + if (GetContext().directive == llvm::acc::ACCD_enter_data || + GetContext().directive == llvm::acc::ACCD_exit_data) { + context_.Say(GetContext().clauseSource, + "Modifier is not allowed for the %s clause " + "on the %s directive"_err_en_US, + parser::ToUpperCaseLetters(getClauseName(clause).str()), + ContextDirectiveAsFortran()); + return true; + } + return false; +} + void AccStructureChecker::Enter(const parser::AccClause &x) { SetContextClause(x); } @@ -375,6 +388,8 @@ void AccStructureChecker::Enter(const parser::AccClause::Copyin &c) { const auto &modifierClause{c.v}; if (const auto &modifier{ std::get>(modifierClause.t)}) { + if (CheckAllowedModifier(llvm::acc::Clause::ACCC_copyin)) + return; if (modifier->v != parser::AccDataModifier::Modifier::ReadOnly) { context_.Say(GetContext().clauseSource, "Only the READONLY modifier is allowed for the %s clause " @@ -392,6 +407,8 @@ void AccStructureChecker::Enter(const parser::AccClause::Copyout &c) { const auto &modifierClause{c.v}; if (const auto &modifier{ std::get>(modifierClause.t)}) { + if (CheckAllowedModifier(llvm::acc::Clause::ACCC_copyout)) + return; if (modifier->v != parser::AccDataModifier::Modifier::Zero) { context_.Say(GetContext().clauseSource, "Only the ZERO modifier is allowed for the %s clause " diff --git a/flang/lib/Semantics/check-acc-structure.h b/flang/lib/Semantics/check-acc-structure.h index f45878bbad66..4373ffc60a91 100644 --- a/flang/lib/Semantics/check-acc-structure.h +++ b/flang/lib/Semantics/check-acc-structure.h @@ -115,6 +115,8 @@ private: const llvm::acc::Directive directive, const parser::CharBlock &directiveSource) const; + bool CheckAllowedModifier(llvm::acc::Clause clause); + llvm::StringRef getClauseName(llvm::acc::Clause clause) override; llvm::StringRef getDirectiveName(llvm::acc::Directive directive) override; }; diff --git a/flang/test/Semantics/acc-clause-validity.f90 b/flang/test/Semantics/acc-clause-validity.f90 index 188d41f6e2a4..3cc1ca28aa49 100644 --- a/flang/test/Semantics/acc-clause-validity.f90 +++ b/flang/test/Semantics/acc-clause-validity.f90 @@ -45,9 +45,12 @@ program openacc_clause_validity !ERROR: At least one of ATTACH, COPYIN, CREATE clause must appear on the ENTER DATA directive !$acc enter data - !ERROR: Only the READONLY modifier is allowed for the COPYIN clause on the ENTER DATA directive + !ERROR: Modifier is not allowed for the COPYIN clause on the ENTER DATA directive !$acc enter data copyin(zero: i) + !ERROR: Modifier is not allowed for the COPYOUT clause on the EXIT DATA directive + !$acc exit data copyout(zero: i) + !ERROR: Only the ZERO modifier is allowed for the CREATE clause on the ENTER DATA directive !$acc enter data create(readonly: i)