diff --git a/flang/test/Semantics/acc-clause-validity.f90 b/flang/test/Semantics/acc-clause-validity.f90 --- a/flang/test/Semantics/acc-clause-validity.f90 +++ b/flang/test/Semantics/acc-clause-validity.f90 @@ -14,6 +14,7 @@ ! 2.11 Parallel Loop ! 2.11 Kernels Loop ! 2.11 Serial Loop +! 2.14.3 Set ! 2.16.13 Wait program openacc_clause_validity @@ -42,6 +43,32 @@ !$acc init device_type(2, i, j) !$acc init device_num(i) device_type(i, j) if(ifCondition) + !ERROR: At least one of DEFAULT_ASYNC, DEVICE_NUM, DEVICE_TYPE clause must appear on the SET directive + !$acc set + + !ERROR: At least one of DEFAULT_ASYNC, DEVICE_NUM, DEVICE_TYPE clause must appear on the SET directive + !$acc set if(.TRUE.) + + !ERROR: At most one DEFAULT_ASYNC clause can appear on the SET directive + !$acc set default_async(2) default_async(1) + + !ERROR: At most one DEFAULT_ASYNC clause can appear on the SET directive + !$acc set default_async(2) default_async(1) + + !ERROR: At most one DEVICE_NUM clause can appear on the SET directive + !$acc set device_num(1) device_num(i) + + !ERROR: At most one DEVICE_TYPE clause can appear on the SET directive + !$acc set device_type(i) device_type(2, i, j) + + !$acc set default_async(2) + !$acc set default_async(i) + !$acc set device_num(1) + !$acc set device_num(i) + !$acc set device_type(i) + !$acc set device_type(2, i, j) + !$acc set device_num(1) default_async(2) device_type(2, i, j) + !ERROR: At least one of ATTACH, COPYIN, CREATE clause must appear on the ENTER DATA directive !$acc enter data diff --git a/llvm/include/llvm/Frontend/OpenACC/ACC.td b/llvm/include/llvm/Frontend/OpenACC/ACC.td --- a/llvm/include/llvm/Frontend/OpenACC/ACC.td +++ b/llvm/include/llvm/Frontend/OpenACC/ACC.td @@ -415,9 +415,15 @@ // 2.14.3 def ACC_Set : Directive<"set"> { let allowedOnceClauses = [ + VersionedClause, + VersionedClause, + VersionedClause, VersionedClause ]; let requiredClauses = [ + // The three following clauses are also in allowedOnceClauses list due to + // restriction 2255 - Two instances of the same clause may not appear on the + // same directive. VersionedClause, VersionedClause, VersionedClause diff --git a/llvm/include/llvm/TableGen/DirectiveEmitter.h b/llvm/include/llvm/TableGen/DirectiveEmitter.h --- a/llvm/include/llvm/TableGen/DirectiveEmitter.h +++ b/llvm/include/llvm/TableGen/DirectiveEmitter.h @@ -58,7 +58,7 @@ return Records.getAllDerivedDefinitions("Clause"); } - bool CheckRecordsValidity() const; + bool HasValidityErrors() const; private: const llvm::Record *Def; diff --git a/llvm/utils/TableGen/DirectiveEmitter.cpp b/llvm/utils/TableGen/DirectiveEmitter.cpp --- a/llvm/utils/TableGen/DirectiveEmitter.cpp +++ b/llvm/utils/TableGen/DirectiveEmitter.cpp @@ -114,24 +114,24 @@ bool HasDuplicateClauses(const std::vector &Clauses, const Directive &Directive, llvm::StringSet<> &CrtClauses) { - bool hasError = false; + bool HasError = false; for (const auto &C : Clauses) { VersionedClause VerClause{C}; const auto insRes = CrtClauses.insert(VerClause.getClause().getName()); if (!insRes.second) { PrintError("Clause " + VerClause.getClause().getRecordName() + " already defined on directive " + Directive.getRecordName()); - hasError = true; + HasError = true; } } - return hasError; + return HasError; } // Check for duplicate clauses in lists. Clauses cannot appear twice in the // three allowed list. Also, since required implies allowed, clauses cannot // appear in both the allowedClauses and requiredClauses lists. bool HasDuplicateClausesInDirectives(const std::vector &Directives) { - bool hasDuplicate = false; + bool HasDuplicate = false; for (const auto &D : Directives) { Directive Dir{D}; llvm::StringSet<> Clauses; @@ -139,25 +139,25 @@ if (HasDuplicateClauses(Dir.getAllowedClauses(), Dir, Clauses) || HasDuplicateClauses(Dir.getAllowedOnceClauses(), Dir, Clauses) || HasDuplicateClauses(Dir.getAllowedExclusiveClauses(), Dir, Clauses)) { - hasDuplicate = true; + HasDuplicate = true; } // Check for duplicate between allowedClauses and required Clauses.clear(); if (HasDuplicateClauses(Dir.getAllowedClauses(), Dir, Clauses) || HasDuplicateClauses(Dir.getRequiredClauses(), Dir, Clauses)) { - hasDuplicate = true; + HasDuplicate = true; } - if (hasDuplicate) + if (HasDuplicate) PrintFatalError("One or more clauses are defined multiple times on" " directive " + Dir.getRecordName()); } - return hasDuplicate; + return HasDuplicate; } // Check consitency of records. Return true if an error has been detected. // Return false if the records are valid. -bool DirectiveLanguage::CheckRecordsValidity() const { +bool DirectiveLanguage::HasValidityErrors() const { if (getDirectiveLanguages().size() != 1) { PrintFatalError("A single definition of DirectiveLanguage is needed."); return true; @@ -170,7 +170,7 @@ // language void EmitDirectivesDecl(RecordKeeper &Records, raw_ostream &OS) { const auto DirLang = DirectiveLanguage{Records}; - if (DirLang.CheckRecordsValidity()) + if (DirLang.HasValidityErrors()) return; OS << "#ifndef LLVM_" << DirLang.getName() << "_INC\n"; @@ -648,7 +648,7 @@ // language. void EmitDirectivesGen(RecordKeeper &Records, raw_ostream &OS) { const auto DirLang = DirectiveLanguage{Records}; - if (DirLang.CheckRecordsValidity()) + if (DirLang.HasValidityErrors()) return; EmitDirectivesFlangImpl(DirLang, OS); @@ -658,7 +658,7 @@ // language. This code can be included in library. void EmitDirectivesImpl(RecordKeeper &Records, raw_ostream &OS) { const auto DirLang = DirectiveLanguage{Records}; - if (DirLang.CheckRecordsValidity()) + if (DirLang.HasValidityErrors()) return; if (!DirLang.getIncludeHeader().empty())