Skip to content

Commit 8e75808

Browse files
Add semantic check for align clause
1 parent 203270a commit 8e75808

File tree

4 files changed

+60
-9
lines changed

4 files changed

+60
-9
lines changed

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,11 +1483,24 @@ void OmpStructureChecker::Leave(const parser::OpenMPRequiresConstruct &) {
14831483
dirContext_.pop_back();
14841484
}
14851485

1486+
void OmpStructureChecker::CheckAlignValue(const parser::OmpClause &clause) {
1487+
if (auto *align{std::get_if<parser::OmpClause::Align>(&clause.u)}) {
1488+
if (const auto &v{GetIntValue(align->v)}; !v || *v <= 0) {
1489+
context_.Say(clause.source,
1490+
"The alignment value should be a constant positive integer"_err_en_US);
1491+
}
1492+
}
1493+
}
1494+
14861495
void OmpStructureChecker::Enter(const parser::OpenMPDeclarativeAllocate &x) {
14871496
isPredefinedAllocator = true;
14881497
const auto &dir{std::get<parser::Verbatim>(x.t)};
14891498
const auto &objectList{std::get<parser::OmpObjectList>(x.t)};
14901499
PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_allocate);
1500+
const auto &clauseList{std::get<parser::OmpClauseList>(x.t)};
1501+
for (const auto &clause : clauseList.v) {
1502+
CheckAlignValue(clause);
1503+
}
14911504
CheckIsVarPartOfAnotherVar(dir.source, objectList);
14921505
}
14931506

@@ -1704,6 +1717,10 @@ void OmpStructureChecker::Enter(const parser::OpenMPExecutableAllocate &x) {
17041717
const auto &dir{std::get<parser::Verbatim>(x.t)};
17051718
const auto &objectList{std::get<std::optional<parser::OmpObjectList>>(x.t)};
17061719
PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_allocate);
1720+
const auto &clauseList{std::get<parser::OmpClauseList>(x.t)};
1721+
for (const auto &clause : clauseList.v) {
1722+
CheckAlignValue(clause);
1723+
}
17071724
if (objectList) {
17081725
CheckIsVarPartOfAnotherVar(dir.source, *objectList);
17091726
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,8 @@ class OmpStructureChecker
261261
void CheckAllowedRequiresClause(llvmOmpClause clause);
262262
bool deviceConstructFound_{false};
263263

264+
void CheckAlignValue(const parser::OmpClause &);
265+
264266
void EnterDirectiveNest(const int index) { directiveNest_[index]++; }
265267
void ExitDirectiveNest(const int index) { directiveNest_[index]--; }
266268
int GetDirectiveNest(const int index) { return directiveNest_[index]; }

flang/test/Parser/OpenMP/allocate-align-tree.f90

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,16 @@
55
! Ensures associated declarative OMP allocations are nested in their
66
! corresponding executable allocate directive
77

8-
program allocate_tree
8+
program allocate_align_tree
99
use omp_lib
10-
integer, allocatable :: j
11-
!$omp allocate(j) align(16)
12-
allocate(j)
13-
end program allocate_tree
10+
integer, allocatable :: j(:), xarray(:)
11+
integer :: z, t
12+
t = 2
13+
z = 3
14+
!$omp allocate(j) align(16)
15+
!$omp allocate(xarray) align(32) allocator(omp_large_cap_mem_alloc)
16+
allocate(j(z), xarray(t))
17+
end program allocate_align_tree
1418

1519
!CHECK: | | DeclarationConstruct -> SpecificationConstruct -> TypeDeclarationStmt
1620
!CHECK-NEXT: | | | DeclarationTypeSpec -> IntrinsicTypeSpec -> IntegerTypeSpec ->
@@ -21,10 +25,18 @@ end program allocate_tree
2125

2226
!CHECK: | | ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPExecutableAllocate
2327
!CHECK-NEXT: | | | Verbatim
24-
!CHECK-NEXT: | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'j'
25-
!CHECK-NEXT: | | | OmpClauseList -> OmpClause -> Align -> OmpAlignClause -> Scalar -> Integer -> Expr = '16_4'
26-
!CHECK-NEXT: | | | | LiteralConstant -> IntLiteralConstant = '16'
28+
!CHECK-NEXT: | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'xarray'
29+
!CHECK-NEXT: | | | OmpClauseList -> OmpClause -> Align -> OmpAlignClause -> Scalar -> Integer -> Expr = '32_4'
30+
!CHECK-NEXT: | | | | LiteralConstant -> IntLiteralConstant = '32'
31+
!CHECK-NEXT: | | | OmpClause -> Allocator -> Scalar -> Integer -> Expr = '2_8'
32+
!CHECK-NEXT: | | | | Designator -> DataRef -> Name = 'omp_large_cap_mem_alloc'
33+
!CHECK-NEXT: | | | OpenMPDeclarativeAllocate
34+
!CHECK-NEXT: | | | | Verbatim
35+
!CHECK-NEXT: | | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'j'
36+
!CHECK-NEXT: | | | | OmpClauseList -> OmpClause -> Align -> OmpAlignClause -> Scalar -> Integer -> Expr = '16_4'
37+
!CHECK-NEXT: | | | | | LiteralConstant -> IntLiteralConstant = '16'
2738
!CHECK-NEXT: | | | AllocateStmt
2839

2940
!UNPARSE: !$OMP ALLOCATE (j) ALIGN(16_4)
30-
!UNPARSE-NEXT: ALLOCATE(j)
41+
!UNPARSE: !$OMP ALLOCATE (xarray) ALIGN(32_4) ALLOCATOR(2_8)
42+
!UNPARSE-NEXT: ALLOCATE(j(z), xarray(t))
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
! REQUIRES: openmp_runtime
2+
3+
! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=51
4+
! OpenMP Version 5.2
5+
! The allocate clause's allocator modifier must be of type allocator_handle
6+
! and the align modifier must be constant, positive integer expression
7+
8+
program allocate_align_tree
9+
use omp_lib
10+
integer, allocatable :: j(:), xarray(:)
11+
integer :: z, t, xx
12+
t = 2
13+
z = 3
14+
!ERROR: The alignment value should be a constant positive integer
15+
!$omp allocate(j) align(xx)
16+
!ERROR: The alignment value should be a constant positive integer
17+
!$omp allocate(xarray) align(-32) allocator(omp_large_cap_mem_alloc)
18+
allocate(j(z), xarray(t))
19+
end program allocate_align_tree
20+

0 commit comments

Comments
 (0)