Skip to content

Commit 81cdf94

Browse files
authored
[clang][OpenMP] Fix region nesting check for scan directive (#98386)
The previous check was inconsistent. For example, it would allow ``` #pragma omp target #pragma omp parallel for for (...) { #pragma omp scan } ``` but not ``` #pragma omp target parallel for for (...) { #pragma omp scan } ``` Make the check conform to the wording on the specification.
1 parent a3913a1 commit 81cdf94

File tree

2 files changed

+15
-20
lines changed

2 files changed

+15
-20
lines changed

clang/lib/Sema/SemaOpenMP.cpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4989,14 +4989,19 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
49894989
OrphanSeen = ParentRegion == OMPD_unknown;
49904990
Recommend = ShouldBeInTargetRegion;
49914991
} else if (CurrentRegion == OMPD_scan) {
4992-
// OpenMP [2.16, Nesting of Regions]
4993-
// If specified, a teams construct must be contained within a target
4994-
// construct.
4995-
NestingProhibited =
4996-
SemaRef.LangOpts.OpenMP < 50 ||
4997-
(ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
4998-
ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
4999-
ParentRegion != OMPD_parallel_for_simd);
4992+
if (SemaRef.LangOpts.OpenMP >= 50) {
4993+
SmallVector<OpenMPDirectiveKind, 4> LeafOrComposite;
4994+
std::ignore = getLeafOrCompositeConstructs(ParentRegion, LeafOrComposite);
4995+
// OpenMP spec 5.0 and 5.1 require scan to be directly enclosed by for,
4996+
// simd, or for simd. This has to take into account combined directives.
4997+
// In 5.2 this seems to be implied by the fact that the specified
4998+
// separated constructs are do, for, and simd.
4999+
OpenMPDirectiveKind Enclosing = LeafOrComposite.back();
5000+
NestingProhibited = Enclosing != OMPD_for && Enclosing != OMPD_simd &&
5001+
Enclosing != OMPD_for_simd;
5002+
} else {
5003+
NestingProhibited = true;
5004+
}
50005005
OrphanSeen = ParentRegion == OMPD_unknown;
50015006
Recommend = ShouldBeInLoopSimdRegion;
50025007
}

clang/test/OpenMP/Inputs/nesting_of_regions.cpp

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5346,11 +5346,6 @@ void foo() {
53465346
}
53475347
#pragma omp target parallel for
53485348
for (int i = 0; i < 10; ++i) {
5349-
#pragma omp scan // expected-error {{region cannot be closely nested inside 'target parallel for' region}}
5350-
bar();
5351-
}
5352-
#pragma omp target parallel for
5353-
for (int i = 0; i < 10; ++i) {
53545349
#pragma omp taskwait
53555350
bar();
53565351
}
@@ -7146,7 +7141,7 @@ void foo() {
71467141
}
71477142
#pragma omp target simd
71487143
for (int i = 0; i < 10; ++i) {
7149-
#pragma omp scan // omp45-error {{OpenMP constructs may not be nested inside a simd region}} omp50-error {{region cannot be closely nested inside 'target simd' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, for simd, parallel for, or parallel for simd region?}} omp51-error {{region cannot be closely nested inside 'target simd' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, for simd, parallel for, or parallel for simd region?}}
7144+
#pragma omp scan // omp45-error {{OpenMP constructs may not be nested inside a simd region}} omp50-error {{exactly one of 'inclusive' or 'exclusive' clauses is expected}} omp51-error {{exactly one of 'inclusive' or 'exclusive' clauses is expected}}
71507145
bar();
71517146
}
71527147
#pragma omp target simd
@@ -14583,11 +14578,6 @@ void foo() {
1458314578
}
1458414579
#pragma omp target parallel for
1458514580
for (int i = 0; i < 10; ++i) {
14586-
#pragma omp scan // expected-error {{region cannot be closely nested inside 'target parallel for' region}}
14587-
bar();
14588-
}
14589-
#pragma omp target parallel for
14590-
for (int i = 0; i < 10; ++i) {
1459114581
#pragma omp taskwait
1459214582
bar();
1459314583
}
@@ -16685,7 +16675,7 @@ void foo() {
1668516675
}
1668616676
#pragma omp target simd
1668716677
for (int i = 0; i < 10; ++i) {
16688-
#pragma omp scan // omp45-error {{OpenMP constructs may not be nested inside a simd region}} omp50-error {{region cannot be closely nested inside 'target simd' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, for simd, parallel for, or parallel for simd region?}} omp51-error {{region cannot be closely nested inside 'target simd' region; perhaps you forget to enclose 'omp scan' directive into a for, simd, for simd, parallel for, or parallel for simd region?}}
16678+
#pragma omp scan // omp45-error {{OpenMP constructs may not be nested inside a simd region}} omp50-error {{exactly one of 'inclusive' or 'exclusive' clauses is expected}} omp51-error {{exactly one of 'inclusive' or 'exclusive' clauses is expected}}
1668916679
bar();
1669016680
}
1669116681
#pragma omp target simd

0 commit comments

Comments
 (0)