diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index 0b64a4a9801cc..10a56e932681b 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -848,11 +848,21 @@ void OmpStructureChecker::CheckTargetNest(const parser::OpenMPConstruct &c) { }, c.u); }, + [&](const parser::OpenMPLoopConstruct &c) { + const auto &beginLoopDir{ + std::get(c.t)}; + const auto &beginDir{ + std::get(beginLoopDir.t)}; + if (llvm::omp::allTargetSet.test(beginDir.v)) { + eligibleTarget = false; + ineligibleTargetDir = beginDir.v; + } + }, [&](const auto &c) {}, }, c.u); if (!eligibleTarget) { - context_.Warn(common::UsageWarning::Portability, + context_.Warn(common::UsageWarning::OpenMPUsage, parser::FindSourceLocation(c), "If %s directive is nested inside TARGET region, the behaviour is unspecified"_port_en_US, parser::ToUpperCaseLetters( @@ -1066,7 +1076,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) { CheckMatching(beginDir, endDir); PushContextAndClauseSets(beginDir.source, beginDir.v); - if (GetContext().directive == llvm::omp::Directive::OMPD_target) { + if (llvm::omp::allTargetSet.test(GetContext().directive)) { EnterDirectiveNest(TargetNest); } @@ -1149,7 +1159,7 @@ void OmpStructureChecker::Leave(const parser::OpenMPBlockConstruct &) { if (GetDirectiveNest(TargetBlockOnlyTeams)) { ExitDirectiveNest(TargetBlockOnlyTeams); } - if (GetContext().directive == llvm::omp::Directive::OMPD_target) { + if (llvm::omp::allTargetSet.test(GetContext().directive)) { ExitDirectiveNest(TargetNest); } dirContext_.pop_back(); diff --git a/flang/test/Semantics/OpenMP/nested-target.f90 b/flang/test/Semantics/OpenMP/nested-target.f90 index 2267f70715d3e..f42b5dde6a08d 100644 --- a/flang/test/Semantics/OpenMP/nested-target.f90 +++ b/flang/test/Semantics/OpenMP/nested-target.f90 @@ -5,7 +5,7 @@ ! 2.12.5 Target Construct program main - integer :: i, j, N = 10 + integer :: i, j, N = 10, n1, n2, res(100) real :: a, arrayA(512), arrayB(512), ai(10) real, allocatable :: B(:) @@ -50,4 +50,28 @@ program main !$omp end target deallocate(B) + n1 = 10 + n2 = 10 + !$omp target teams map(to:a) + !PORTABILITY: If TARGET DATA directive is nested inside TARGET region, the behaviour is unspecified + !$omp target data map(n1,n2) + do i=1, n1 + do j=1, n2 + res((i-1)*10+j) = i*j + end do + end do + !$omp end target data + !$omp end target teams + + !$omp target teams map(to:a) map(from:n1,n2) + !PORTABILITY: If TARGET TEAMS DISTRIBUTE PARALLEL DO directive is nested inside TARGET region, the behaviour is unspecified + !$omp target teams distribute parallel do + do i=1, n1 + do j=1, n2 + res((i-1)*10+j) = i*j + end do + end do + !$omp end target teams distribute parallel do + !$omp end target teams + end program main