forked from OSchip/llvm-project
[flang][openacc] Enforce delcare directive restriction
Add semantic check for most of the restrictions for the declare directive. Reviewed By: kiranktp Differential Revision: https://reviews.llvm.org/D92741
This commit is contained in:
parent
037b058e41
commit
b73736a404
|
@ -134,9 +134,30 @@ void AccStructureChecker::Enter(
|
|||
}
|
||||
|
||||
void AccStructureChecker::Leave(
|
||||
const parser::OpenACCStandaloneDeclarativeConstruct &) {
|
||||
const parser::OpenACCStandaloneDeclarativeConstruct &x) {
|
||||
// Restriction - line 2409
|
||||
CheckAtLeastOneClause();
|
||||
|
||||
// Restriction - line 2417-2418 - In a Fortran module declaration section,
|
||||
// only create, copyin, device_resident, and link clauses are allowed.
|
||||
const auto &declarativeDir{std::get<parser::AccDeclarativeDirective>(x.t)};
|
||||
const auto &scope{context_.FindScope(declarativeDir.source)};
|
||||
const Scope &containingScope{GetProgramUnitContaining(scope)};
|
||||
if (containingScope.kind() == Scope::Kind::Module) {
|
||||
for (auto cl : GetContext().actualClauses) {
|
||||
if (cl != llvm::acc::Clause::ACCC_create &&
|
||||
cl != llvm::acc::Clause::ACCC_copyin &&
|
||||
cl != llvm::acc::Clause::ACCC_device_resident &&
|
||||
cl != llvm::acc::Clause::ACCC_link)
|
||||
context_.Say(GetContext().directiveSource,
|
||||
"%s clause is not allowed on the %s directive in module "
|
||||
"declaration "
|
||||
"section"_err_en_US,
|
||||
parser::ToUpperCaseLetters(
|
||||
llvm::acc::getOpenACCClauseName(cl).str()),
|
||||
ContextDirectiveAsFortran());
|
||||
}
|
||||
}
|
||||
dirContext_.pop_back();
|
||||
}
|
||||
|
||||
|
|
|
@ -124,6 +124,7 @@ public:
|
|||
|
||||
bool Pre(const parser::OpenACCRoutineConstruct &);
|
||||
bool Pre(const parser::AccBindClause &);
|
||||
void Post(const parser::OpenACCStandaloneDeclarativeConstruct &);
|
||||
|
||||
void Post(const parser::AccBeginBlockDirective &) {
|
||||
GetContext().withinConstruct = true;
|
||||
|
@ -215,6 +216,7 @@ private:
|
|||
void CheckMultipleAppearances(
|
||||
const parser::Name &, const Symbol &, Symbol::Flag);
|
||||
void AllowOnlyArrayAndSubArray(const parser::AccObjectList &objectList);
|
||||
void DoNotAllowAssumedSizedArray(const parser::AccObjectList &objectList);
|
||||
};
|
||||
|
||||
// Data-sharing and Data-mapping attributes for data-refs in OpenMP construct
|
||||
|
@ -470,6 +472,60 @@ bool AccAttributeVisitor::Pre(const parser::OpenACCDeclarativeConstruct &x) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static const parser::AccObjectList &GetAccObjectList(
|
||||
const parser::AccClause &clause) {
|
||||
if (const auto *copyClause =
|
||||
std::get_if<Fortran::parser::AccClause::Copy>(&clause.u)) {
|
||||
return copyClause->v;
|
||||
} else if (const auto *createClause =
|
||||
std::get_if<Fortran::parser::AccClause::Create>(&clause.u)) {
|
||||
const Fortran::parser::AccObjectListWithModifier &listWithModifier =
|
||||
createClause->v;
|
||||
const Fortran::parser::AccObjectList &accObjectList =
|
||||
std::get<Fortran::parser::AccObjectList>(listWithModifier.t);
|
||||
return accObjectList;
|
||||
} else if (const auto *copyinClause =
|
||||
std::get_if<Fortran::parser::AccClause::Copyin>(&clause.u)) {
|
||||
const Fortran::parser::AccObjectListWithModifier &listWithModifier =
|
||||
copyinClause->v;
|
||||
const Fortran::parser::AccObjectList &accObjectList =
|
||||
std::get<Fortran::parser::AccObjectList>(listWithModifier.t);
|
||||
return accObjectList;
|
||||
} else if (const auto *copyoutClause =
|
||||
std::get_if<Fortran::parser::AccClause::Copyout>(&clause.u)) {
|
||||
const Fortran::parser::AccObjectListWithModifier &listWithModifier =
|
||||
copyoutClause->v;
|
||||
const Fortran::parser::AccObjectList &accObjectList =
|
||||
std::get<Fortran::parser::AccObjectList>(listWithModifier.t);
|
||||
return accObjectList;
|
||||
} else if (const auto *presentClause =
|
||||
std::get_if<Fortran::parser::AccClause::Present>(&clause.u)) {
|
||||
return presentClause->v;
|
||||
} else if (const auto *deviceptrClause =
|
||||
std::get_if<Fortran::parser::AccClause::Deviceptr>(
|
||||
&clause.u)) {
|
||||
return deviceptrClause->v;
|
||||
} else if (const auto *deviceResidentClause =
|
||||
std::get_if<Fortran::parser::AccClause::DeviceResident>(
|
||||
&clause.u)) {
|
||||
return deviceResidentClause->v;
|
||||
} else if (const auto *linkClause =
|
||||
std::get_if<Fortran::parser::AccClause::Link>(&clause.u)) {
|
||||
return linkClause->v;
|
||||
} else {
|
||||
llvm_unreachable("Clause without object list!");
|
||||
}
|
||||
}
|
||||
|
||||
void AccAttributeVisitor::Post(
|
||||
const parser::OpenACCStandaloneDeclarativeConstruct &x) {
|
||||
const auto &clauseList = std::get<parser::AccClauseList>(x.t);
|
||||
for (const auto &clause : clauseList.v) {
|
||||
// Restriction - line 2414
|
||||
DoNotAllowAssumedSizedArray(GetAccObjectList(clause));
|
||||
}
|
||||
}
|
||||
|
||||
bool AccAttributeVisitor::Pre(const parser::OpenACCLoopConstruct &x) {
|
||||
const auto &beginDir{std::get<parser::AccBeginLoopDirective>(x.t)};
|
||||
const auto &loopDir{std::get<parser::AccLoopDirective>(beginDir.t)};
|
||||
|
@ -588,6 +644,30 @@ void AccAttributeVisitor::AllowOnlyArrayAndSubArray(
|
|||
}
|
||||
}
|
||||
|
||||
void AccAttributeVisitor::DoNotAllowAssumedSizedArray(
|
||||
const parser::AccObjectList &objectList) {
|
||||
for (const auto &accObject : objectList.v) {
|
||||
std::visit(
|
||||
common::visitors{
|
||||
[&](const parser::Designator &designator) {
|
||||
const auto &name{GetLastName(designator)};
|
||||
if (name.symbol && semantics::IsAssumedSizeArray(*name.symbol))
|
||||
context_.Say(designator.source,
|
||||
"Assumed-size dummy arrays may not appear on the %s "
|
||||
"directive"_err_en_US,
|
||||
parser::ToUpperCaseLetters(
|
||||
llvm::acc::getOpenACCDirectiveName(
|
||||
GetContext().directive)
|
||||
.str()));
|
||||
},
|
||||
[&](const auto &name) {
|
||||
|
||||
},
|
||||
},
|
||||
accObject.u);
|
||||
}
|
||||
}
|
||||
|
||||
bool AccAttributeVisitor::Pre(const parser::OpenACCCacheConstruct &x) {
|
||||
const auto &verbatim{std::get<parser::Verbatim>(x.t)};
|
||||
PushContext(verbatim.source, llvm::acc::Directive::ACCD_cache);
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
! 2.5.3 Kernels
|
||||
! 2.9 Loop
|
||||
! 2.12 Atomic
|
||||
! 2.13 Declare
|
||||
! 2.14.3 Set
|
||||
! 2.14.4 Update
|
||||
! 2.15.1 Routine
|
||||
|
@ -42,8 +41,6 @@ program openacc_clause_validity
|
|||
type(atype) :: t
|
||||
type(atype), dimension(10) :: ta
|
||||
|
||||
!ERROR: At least one clause is required on the DECLARE directive
|
||||
!$acc declare
|
||||
real(8), dimension(N) :: a, f, g, h
|
||||
|
||||
!$acc init
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
! RUN: %S/test_errors.sh %s %t %f18 -fopenacc
|
||||
|
||||
! Check OpenACC clause validity for the following construct and directive:
|
||||
! 2.13 Declare
|
||||
|
||||
module openacc_declare_validity
|
||||
|
||||
implicit none
|
||||
|
||||
real(8), dimension(10) :: aa, bb, ab, cc
|
||||
|
||||
!ERROR: At least one clause is required on the DECLARE directive
|
||||
!$acc declare
|
||||
|
||||
!$acc declare create(aa, bb)
|
||||
|
||||
!$acc declare link(ab)
|
||||
|
||||
!$acc declare device_resident(cc)
|
||||
|
||||
!ERROR: COPYOUT clause is not allowed on the DECLARE directive in module declaration section
|
||||
!$acc declare copyout(ab)
|
||||
|
||||
!ERROR: COPY clause is not allowed on the DECLARE directive in module declaration section
|
||||
!$acc declare copy(ab)
|
||||
|
||||
!ERROR: PRESENT clause is not allowed on the DECLARE directive in module declaration section
|
||||
!$acc declare present(ab)
|
||||
|
||||
!ERROR: DEVICEPTR clause is not allowed on the DECLARE directive in module declaration section
|
||||
!$acc declare deviceptr(ab)
|
||||
|
||||
contains
|
||||
|
||||
subroutine sub1(cc, dd)
|
||||
real(8) :: cc(:)
|
||||
real(8) :: dd(:)
|
||||
!$acc declare present(cc, dd)
|
||||
end subroutine sub1
|
||||
|
||||
function fct1(ee, ff, gg, hh, ii)
|
||||
integer :: fct1
|
||||
real(8), intent(in) :: ee(:)
|
||||
!$acc declare copyin(readonly: ee)
|
||||
real(8) :: ff(:), hh(:), ii(:,:)
|
||||
!$acc declare link(hh) device_resident(ii)
|
||||
real(8), intent(out) :: gg(:)
|
||||
!$acc declare copy(ff) copyout(gg)
|
||||
end function fct1
|
||||
|
||||
subroutine sub2(cc)
|
||||
real(8), dimension(*) :: cc
|
||||
!ERROR: Assumed-size dummy arrays may not appear on the DECLARE directive
|
||||
!$acc declare present(cc)
|
||||
end subroutine sub2
|
||||
|
||||
end module openacc_declare_validity
|
Loading…
Reference in New Issue