diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -868,6 +868,21 @@ } Symbol::Flag ivDSA{Symbol::Flag::AccPrivate}; + const auto getNextDoConstruct = + [this](const parser::Block &block) -> const parser::DoConstruct * { + for (const auto &entry : block) { + if (const auto *doConstruct = GetDoConstructIf(entry)) { + return doConstruct; + } else if (parser::Unwrap(entry)) { + // It is allowed to have a compiler directive associated with the loop. + continue; + } else { + break; + } + } + return nullptr; + }; + const auto &outer{std::get>(x.t)}; for (const parser::DoConstruct *loop{&*outer}; loop && level > 0; --level) { // go through all the nested do-loops and resolve index variables @@ -879,8 +894,7 @@ } const auto &block{std::get(loop->t)}; - const auto it{block.begin()}; - loop = it != block.end() ? GetDoConstructIf(*it) : nullptr; + loop = getNextDoConstruct(block); } CHECK(level == 0); } diff --git a/flang/test/Semantics/OpenACC/acc-resolve03.f90 b/flang/test/Semantics/OpenACC/acc-resolve03.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/OpenACC/acc-resolve03.f90 @@ -0,0 +1,21 @@ +! RUN: %flang_fc1 -fopenacc %s +! A regression test to check that +! arbitrary compiler directives do not generate errors +! inside OpenACC collapsed loops +subroutine foo + integer, parameter :: loop_bound = 42 + integer :: a + integer :: b + integer :: c + + !$acc parallel + do a = 0, loop_bound + !$acc loop collapse(2) + do b = 0, loop_bound + !dir$ ivdep + do c = 0, loop_bound + enddo + enddo + enddo + !$acc end parallel +end subroutine foo