diff --git a/flang/lib/Semantics/check-acc-structure.cpp b/flang/lib/Semantics/check-acc-structure.cpp index 692a7a408947a..4ae034736a40b 100644 --- a/flang/lib/Semantics/check-acc-structure.cpp +++ b/flang/lib/Semantics/check-acc-structure.cpp @@ -335,6 +335,10 @@ void AccStructureChecker::Enter(const parser::OpenACCCacheConstruct &x) { const auto &verbatim = std::get(x.t); PushContextAndClauseSets(verbatim.source, llvm::acc::Directive::ACCD_cache); SetContextDirectiveSource(verbatim.source); + if (loopNestLevel == 0) { + context_.Say(verbatim.source, + "The CACHE directive must be inside a loop"_err_en_US); + } } void AccStructureChecker::Leave(const parser::OpenACCCacheConstruct &x) { dirContext_.pop_back(); @@ -655,6 +659,14 @@ void AccStructureChecker::Enter(const parser::SeparateModuleSubprogram &) { declareSymbols.clear(); } +void AccStructureChecker::Enter(const parser::DoConstruct &) { + ++loopNestLevel; +} + +void AccStructureChecker::Leave(const parser::DoConstruct &) { + --loopNestLevel; +} + llvm::StringRef AccStructureChecker::getDirectiveName( llvm::acc::Directive directive) { return llvm::acc::getOpenACCDirectiveName(directive); diff --git a/flang/lib/Semantics/check-acc-structure.h b/flang/lib/Semantics/check-acc-structure.h index 8c0d7150dd47b..6d05acba92cb2 100644 --- a/flang/lib/Semantics/check-acc-structure.h +++ b/flang/lib/Semantics/check-acc-structure.h @@ -71,6 +71,8 @@ class AccStructureChecker void Enter(const parser::SubroutineSubprogram &); void Enter(const parser::FunctionSubprogram &); void Enter(const parser::SeparateModuleSubprogram &); + void Enter(const parser::DoConstruct &); + void Leave(const parser::DoConstruct &); #define GEN_FLANG_CLAUSE_CHECK_ENTER #include "llvm/Frontend/OpenACC/ACC.inc" @@ -88,6 +90,7 @@ class AccStructureChecker llvm::StringRef getDirectiveName(llvm::acc::Directive directive) override; llvm::SmallDenseSet declareSymbols; + unsigned loopNestLevel = 0; }; } // namespace Fortran::semantics diff --git a/flang/test/Semantics/OpenACC/acc-cache-validity.f90 b/flang/test/Semantics/OpenACC/acc-cache-validity.f90 index 9afdd6def21fd..9eb12b9e2b7e4 100644 --- a/flang/test/Semantics/OpenACC/acc-cache-validity.f90 +++ b/flang/test/Semantics/OpenACC/acc-cache-validity.f90 @@ -19,6 +19,8 @@ program openacc_cache_validity type(atype), dimension(10) :: ta real(8), dimension(N) :: a + do i = 1, N + !$acc cache(a(i)) !$acc cache(a(1:2,3:4)) !$acc cache(a) @@ -40,4 +42,9 @@ program openacc_cache_validity !ERROR: Only array element or subarray are allowed in CACHE directive !$acc cache(/i/) + end do + + !ERROR: The CACHE directive must be inside a loop + !$acc cache(a) + end program openacc_cache_validity