[flang][openacc] Enforce no modifier on enter data and exit data clauses
authorValentin Clement <clementval@gmail.com>
Thu, 29 Oct 2020 13:53:10 +0000 (09:53 -0400)
committerclementval <clementval@gmail.com>
Thu, 29 Oct 2020 13:53:22 +0000 (09:53 -0400)
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
flang/lib/Semantics/check-acc-structure.h
flang/test/Semantics/acc-clause-validity.f90

index 8adb15e..4559050 100644 (file)
@@ -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<std::optional<parser::AccDataModifier>>(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<std::optional<parser::AccDataModifier>>(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 "
index f45878b..4373ffc 100644 (file)
@@ -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;
 };
index 188d41f..3cc1ca2 100644 (file)
@@ -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)