[flang] Add semantic checks for threadprivate and declare target directives

This patch supports the following checks:
```
[5.1] 2.21.2 THREADPRIVATE Directive
The threadprivate directive must appear in the declaration section of
a scoping unit in which the common block or variable is declared.
[5.1] 2.14.7 Declare Target Directive
The directive must appear in the declaration section of a scoping unit
in which the common block or variable is declared.
```
Reviewed By: kiranchandramohan, shraiysh, NimishMishra

Differential Revision: https://reviews.llvm.org/D125767
This commit is contained in:
PeixinQiao 2022-06-01 22:40:51 +08:00
parent 7047d79fde
commit 0a90b72c43
3 changed files with 96 additions and 0 deletions

View File

@ -922,6 +922,8 @@ void OmpStructureChecker::CheckThreadprivateOrDeclareTargetVar(
common::visitors{
[&](const parser::Designator &) {
if (const auto *name{parser::Unwrap<parser::Name>(ompObject)}) {
const auto &useScope{
context_.FindScope(GetContext().directiveSource)};
const auto &declScope{
GetProgramUnitContaining(name->symbol->GetUltimate())};
const auto *sym =
@ -967,6 +969,12 @@ void OmpStructureChecker::CheckThreadprivateOrDeclareTargetVar(
"declared in the scope of a module or have the SAVE "
"attribute, either explicitly or implicitly"_err_en_US,
ContextDirectiveAsFortran());
} else if (useScope != declScope) {
context_.Say(name->source,
"The %s directive and the common block or variable in it "
"must appear in the same declaration section of a "
"scoping unit"_err_en_US,
ContextDirectiveAsFortran());
} else if (FindEquivalenceSet(*name->symbol)) {
context_.Say(name->source,
"A variable in a %s directive cannot appear in an "

View File

@ -0,0 +1,44 @@
! RUN: %python %S/test_errors.py %s %flang_fc1 -fopenmp
! OpenMP Version 5.1
! Check OpenMP construct validity for the following directives:
! 2.14.7 Declare Target Directive
module mod0
integer :: mi
contains
subroutine subm()
integer, save :: mmi
!ERROR: The DECLARE TARGET directive and the common block or variable in it must appear in the same declaration section of a scoping unit
!$omp declare target (mi)
mi = 1
contains
subroutine subsubm()
!ERROR: The DECLARE TARGET directive and the common block or variable in it must appear in the same declaration section of a scoping unit
!$omp declare target (mmi)
end
end
end
module mod1
integer :: mod_i
end
program main
use mod1
integer, save :: i
integer :: j
!ERROR: The DECLARE TARGET directive and the common block or variable in it must appear in the same declaration section of a scoping unit
!$omp declare target (mod_i)
contains
subroutine sub()
!ERROR: The DECLARE TARGET directive and the common block or variable in it must appear in the same declaration section of a scoping unit
!ERROR: The DECLARE TARGET directive and the common block or variable in it must appear in the same declaration section of a scoping unit
!$omp declare target (i, j)
i = 1
j = 1
end
end

View File

@ -0,0 +1,44 @@
! RUN: %python %S/test_errors.py %s %flang_fc1 -fopenmp
! OpenMP Version 5.1
! Check OpenMP construct validity for the following directives:
! 2.21.2 Threadprivate Directive
module mod0
integer :: mi
contains
subroutine subm()
integer, save :: mmi
!ERROR: The THREADPRIVATE directive and the common block or variable in it must appear in the same declaration section of a scoping unit
!$omp threadprivate(mi)
mi = 1
contains
subroutine subsubm()
!ERROR: The THREADPRIVATE directive and the common block or variable in it must appear in the same declaration section of a scoping unit
!$omp threadprivate(mmi)
end
end
end
module mod1
integer :: mod_i
end
program main
use mod1
integer, save :: i
integer :: j
!ERROR: The THREADPRIVATE directive and the common block or variable in it must appear in the same declaration section of a scoping unit
!$omp threadprivate(mod_i)
contains
subroutine sub()
!ERROR: The THREADPRIVATE directive and the common block or variable in it must appear in the same declaration section of a scoping unit
!ERROR: The THREADPRIVATE directive and the common block or variable in it must appear in the same declaration section of a scoping unit
!$omp threadprivate(i, j)
i = 1
j = 1
end
end