Skip to content

Commit 2a5bc0a

Browse files
committed
Add error for nesting of non loop transformation constructs
1 parent db2b677 commit 2a5bc0a

File tree

3 files changed

+38
-22
lines changed

3 files changed

+38
-22
lines changed

flang/lib/Semantics/canonicalize-omp.cpp

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -164,30 +164,34 @@ class CanonicalizationOfOmp {
164164
std::get<parser::OmpBeginLoopDirective>(ompLoopCons->t);
165165
auto &beginLoopDirective =
166166
std::get<parser::OmpLoopDirective>(beginDirective.t);
167-
// iterate through the remaining block items to find the end directive for the unroll/tile directive.
168-
parser::Block::iterator endIt;
169-
endIt = nextIt;
170-
while(endIt != block.end()) {
171-
if (auto *endDir{
172-
GetConstructIf<parser::OmpEndLoopDirective>(*endIt)}) {
173-
auto &endLoopDirective = std::get<parser::OmpLoopDirective>(endDir->t);
174-
if(endLoopDirective.v == dir.v) {
175-
std::get<std::optional<parser::OmpEndLoopDirective>>(x.t) =
176-
std::move(*endDir);
177-
endIt = block.erase(endIt);
178-
continue;
167+
if ((beginLoopDirective.v == llvm::omp::Directive::OMPD_unroll ||
168+
beginLoopDirective.v == llvm::omp::Directive::OMPD_tile)) {
169+
// iterate through the remaining block items to find the end directive for the unroll/tile directive.
170+
parser::Block::iterator endIt;
171+
endIt = nextIt;
172+
while(endIt != block.end()) {
173+
if (auto *endDir{
174+
GetConstructIf<parser::OmpEndLoopDirective>(*endIt)}) {
175+
auto &endLoopDirective = std::get<parser::OmpLoopDirective>(endDir->t);
176+
if(endLoopDirective.v == dir.v) {
177+
std::get<std::optional<parser::OmpEndLoopDirective>>(x.t) =
178+
std::move(*endDir);
179+
endIt = block.erase(endIt);
180+
continue;
181+
}
179182
}
183+
++endIt;
180184
}
181-
++endIt;
182-
}
183-
if ((beginLoopDirective.v == llvm::omp::Directive::OMPD_unroll ||
184-
beginLoopDirective.v == llvm::omp::Directive::OMPD_tile)) {
185185
RewriteOpenMPLoopConstruct(*ompLoopCons, block, nextIt);
186186
auto &ompLoop = std::get<std::optional<std::variant<parser::DoConstruct, common::Indirection<parser::OpenMPLoopConstruct>>>>(x.t);
187187
ompLoop = std::optional<std::variant<parser::DoConstruct, common::Indirection<parser::OpenMPLoopConstruct>>>{
188188
std::variant<parser::DoConstruct, common::Indirection<parser::OpenMPLoopConstruct>>{
189189
common::Indirection{std::move(*ompLoopCons)}}};
190190
nextIt = block.erase(nextIt);
191+
} else {
192+
messages_.Say(dir.source,
193+
"Only OpenMP Loop Transformation Constructs can be nested within OpenMPLoopConstruct's"_err_en_US,
194+
parser::ToUpperCaseLetters(dir.source.ToString()));
191195
}
192196
} else {
193197
missingDoConstruct(dir);

flang/lib/Semantics/check-omp-structure.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -781,12 +781,6 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
781781
(beginDir.v == llvm::omp::Directive::OMPD_distribute_simd)) {
782782
CheckDistLinear(x);
783783
}
784-
if (beginDir.v == llvm::omp::Directive::OMPD_tile) {
785-
const auto &clauses{std::get<parser::OmpClauseList>(beginLoopDir.t)};
786-
for (auto &clause : clauses.v) {
787-
788-
}
789-
}
790784
}
791785
const parser::Name OmpStructureChecker::GetLoopIndex(
792786
const parser::DoConstruct *x) {

flang/test/Semantics/OpenMP/loop-transformation-construct01.f90

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,21 @@ subroutine loop_transformation_construct2
2626
!ERROR: The END TILE directive must follow the DO loop associated with the loop construct
2727
!$omp end tile
2828
end subroutine
29+
30+
subroutine loop_transformation_construct2
31+
implicit none
32+
integer :: i = 5
33+
integer :: y
34+
integer :: v(i)
35+
36+
!$omp do
37+
!ERROR: Only OpenMP Loop Transformation Constructs can be nested within OpenMPLoopConstruct's
38+
!$omp parallel do
39+
do x = 1, i
40+
v(x) = x(x) * 2
41+
end do
42+
!! This error occurs because the `parallel do` end directive never gets matched.
43+
!ERROR: The END PARALLEL DO directive must follow the DO loop associated with the loop construct
44+
!$omp end parallel do
45+
!$omp end do
46+
end subroutine

0 commit comments

Comments
 (0)