From 75ba29ac5654b622107653a0fd33f84846b4e39f Mon Sep 17 00:00:00 2001 From: Valentin Clement Date: Thu, 29 Oct 2020 09:53:10 -0400 Subject: [PATCH] [flang][openacc] Enforce no modifier on enter data and exit data clauses Enter data can have the copyin clause and exit data can have the copyout clause. Both clauses support modifier with other directive but for these two directives no modifier are supported. This semantic check enforce this rule. Reviewed By: kiranktp Differential Revision: https://reviews.llvm.org/D90280 --- flang/lib/Semantics/check-acc-structure.cpp | 17 +++++++++++++++++ flang/lib/Semantics/check-acc-structure.h | 2 ++ flang/test/Semantics/acc-clause-validity.f90 | 5 ++++- 3 files changed, 23 insertions(+), 1 deletion(-) 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)