[flang][OpenMP] Semantic checks for DYN_GROUPPRIVATE
Add checks for non-STRICT values of the prescriptiveness modifier on clauses that had accepted it prior to the addition of FALLBACK value (GRAINSIZE and NUM_TASKS).
This commit is contained in:
parent
f54e18d9d5
commit
e00ef602a8
@ -67,6 +67,7 @@ template <typename SpecificTy> const OmpModifierDescriptor &OmpGetDescriptor();
|
|||||||
#define DECLARE_DESCRIPTOR(name) \
|
#define DECLARE_DESCRIPTOR(name) \
|
||||||
template <> const OmpModifierDescriptor &OmpGetDescriptor<name>()
|
template <> const OmpModifierDescriptor &OmpGetDescriptor<name>()
|
||||||
|
|
||||||
|
DECLARE_DESCRIPTOR(parser::OmpAccessGroup);
|
||||||
DECLARE_DESCRIPTOR(parser::OmpAlignment);
|
DECLARE_DESCRIPTOR(parser::OmpAlignment);
|
||||||
DECLARE_DESCRIPTOR(parser::OmpAlignModifier);
|
DECLARE_DESCRIPTOR(parser::OmpAlignModifier);
|
||||||
DECLARE_DESCRIPTOR(parser::OmpAllocatorComplexModifier);
|
DECLARE_DESCRIPTOR(parser::OmpAllocatorComplexModifier);
|
||||||
|
@ -471,6 +471,45 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Hint &x) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OmpStructureChecker::Enter(const parser::OmpClause::DynGroupprivate &x) {
|
||||||
|
CheckAllowedClause(llvm::omp::Clause::OMPC_dyn_groupprivate);
|
||||||
|
parser::CharBlock source{GetContext().clauseSource};
|
||||||
|
|
||||||
|
OmpVerifyModifiers(x.v, llvm::omp::OMPC_dyn_groupprivate, source, context_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OmpStructureChecker::Enter(const parser::OmpClause::Grainsize &x) {
|
||||||
|
CheckAllowedClause(llvm::omp::Clause::OMPC_grainsize);
|
||||||
|
parser::CharBlock source{GetContext().clauseSource};
|
||||||
|
|
||||||
|
if (OmpVerifyModifiers(x.v, llvm::omp::OMPC_grainsize, source, context_)) {
|
||||||
|
auto &modifiers{OmpGetModifiers(x.v)};
|
||||||
|
for (auto *mod :
|
||||||
|
OmpGetRepeatableModifier<parser::OmpPrescriptiveness>(modifiers)) {
|
||||||
|
if (mod->v != parser::OmpPrescriptiveness::Value::Strict) {
|
||||||
|
context_.Say(OmpGetModifierSource(modifiers, mod),
|
||||||
|
"Only STRICT is allowed as prescriptiveness on this clause"_err_en_US);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OmpStructureChecker::Enter(const parser::OmpClause::NumTasks &x) {
|
||||||
|
CheckAllowedClause(llvm::omp::Clause::OMPC_num_tasks);
|
||||||
|
parser::CharBlock source{GetContext().clauseSource};
|
||||||
|
|
||||||
|
if (OmpVerifyModifiers(x.v, llvm::omp::OMPC_num_tasks, source, context_)) {
|
||||||
|
auto &modifiers{OmpGetModifiers(x.v)};
|
||||||
|
for (auto *mod :
|
||||||
|
OmpGetRepeatableModifier<parser::OmpPrescriptiveness>(modifiers)) {
|
||||||
|
if (mod->v != parser::OmpPrescriptiveness::Value::Strict) {
|
||||||
|
context_.Say(OmpGetModifierSource(modifiers, mod),
|
||||||
|
"Only STRICT is allowed as prescriptiveness on this clause"_err_en_US);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void OmpStructureChecker::Enter(const parser::OmpDirectiveSpecification &x) {
|
void OmpStructureChecker::Enter(const parser::OmpDirectiveSpecification &x) {
|
||||||
// OmpDirectiveSpecification exists on its own only in METADIRECTIVE.
|
// OmpDirectiveSpecification exists on its own only in METADIRECTIVE.
|
||||||
// In other cases it's a part of other constructs that handle directive
|
// In other cases it's a part of other constructs that handle directive
|
||||||
@ -2542,6 +2581,32 @@ void OmpStructureChecker::Leave(const parser::OmpClauseList &) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Default access-group for DYN_GROUPPRIVATE is "cgroup". On a given
|
||||||
|
// construct there can be at most one DYN_GROUPPRIVATE with a given
|
||||||
|
// access-group.
|
||||||
|
const parser::OmpClause
|
||||||
|
*accGrpClause[parser::OmpAccessGroup::Value_enumSize] = {nullptr};
|
||||||
|
for (auto [_, clause] :
|
||||||
|
FindClauses(llvm::omp::Clause::OMPC_dyn_groupprivate)) {
|
||||||
|
auto &wrapper{std::get<parser::OmpClause::DynGroupprivate>(clause->u)};
|
||||||
|
auto &modifiers{OmpGetModifiers(wrapper.v)};
|
||||||
|
auto accGrp{parser::OmpAccessGroup::Value::Cgroup};
|
||||||
|
if (auto *ag{OmpGetUniqueModifier<parser::OmpAccessGroup>(modifiers)}) {
|
||||||
|
accGrp = ag->v;
|
||||||
|
}
|
||||||
|
auto &firstClause{accGrpClause[llvm::to_underlying(accGrp)]};
|
||||||
|
if (firstClause) {
|
||||||
|
context_
|
||||||
|
.Say(clause->source,
|
||||||
|
"The access-group modifier can only occur on a single clause in a construct"_err_en_US)
|
||||||
|
.Attach(firstClause->source,
|
||||||
|
"Previous clause with access-group modifier"_en_US);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
firstClause = clause;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CheckRequireAtLeastOneOf();
|
CheckRequireAtLeastOneOf();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2593,18 +2658,15 @@ CHECK_SIMPLE_CLAUSE(Default, OMPC_default)
|
|||||||
CHECK_SIMPLE_CLAUSE(Depobj, OMPC_depobj)
|
CHECK_SIMPLE_CLAUSE(Depobj, OMPC_depobj)
|
||||||
CHECK_SIMPLE_CLAUSE(DeviceType, OMPC_device_type)
|
CHECK_SIMPLE_CLAUSE(DeviceType, OMPC_device_type)
|
||||||
CHECK_SIMPLE_CLAUSE(DistSchedule, OMPC_dist_schedule)
|
CHECK_SIMPLE_CLAUSE(DistSchedule, OMPC_dist_schedule)
|
||||||
CHECK_SIMPLE_CLAUSE(DynGroupprivate, OMPC_dyn_groupprivate)
|
|
||||||
CHECK_SIMPLE_CLAUSE(Exclusive, OMPC_exclusive)
|
CHECK_SIMPLE_CLAUSE(Exclusive, OMPC_exclusive)
|
||||||
CHECK_SIMPLE_CLAUSE(Final, OMPC_final)
|
CHECK_SIMPLE_CLAUSE(Final, OMPC_final)
|
||||||
CHECK_SIMPLE_CLAUSE(Flush, OMPC_flush)
|
CHECK_SIMPLE_CLAUSE(Flush, OMPC_flush)
|
||||||
CHECK_SIMPLE_CLAUSE(Full, OMPC_full)
|
CHECK_SIMPLE_CLAUSE(Full, OMPC_full)
|
||||||
CHECK_SIMPLE_CLAUSE(Grainsize, OMPC_grainsize)
|
|
||||||
CHECK_SIMPLE_CLAUSE(Holds, OMPC_holds)
|
CHECK_SIMPLE_CLAUSE(Holds, OMPC_holds)
|
||||||
CHECK_SIMPLE_CLAUSE(Inclusive, OMPC_inclusive)
|
CHECK_SIMPLE_CLAUSE(Inclusive, OMPC_inclusive)
|
||||||
CHECK_SIMPLE_CLAUSE(Initializer, OMPC_initializer)
|
CHECK_SIMPLE_CLAUSE(Initializer, OMPC_initializer)
|
||||||
CHECK_SIMPLE_CLAUSE(Match, OMPC_match)
|
CHECK_SIMPLE_CLAUSE(Match, OMPC_match)
|
||||||
CHECK_SIMPLE_CLAUSE(Nontemporal, OMPC_nontemporal)
|
CHECK_SIMPLE_CLAUSE(Nontemporal, OMPC_nontemporal)
|
||||||
CHECK_SIMPLE_CLAUSE(NumTasks, OMPC_num_tasks)
|
|
||||||
CHECK_SIMPLE_CLAUSE(Order, OMPC_order)
|
CHECK_SIMPLE_CLAUSE(Order, OMPC_order)
|
||||||
CHECK_SIMPLE_CLAUSE(Read, OMPC_read)
|
CHECK_SIMPLE_CLAUSE(Read, OMPC_read)
|
||||||
CHECK_SIMPLE_CLAUSE(Threadprivate, OMPC_threadprivate)
|
CHECK_SIMPLE_CLAUSE(Threadprivate, OMPC_threadprivate)
|
||||||
|
@ -74,6 +74,22 @@ unsigned OmpModifierDescriptor::since(llvm::omp::Clause id) const {
|
|||||||
// Note: The intent for these functions is to have them be automatically-
|
// Note: The intent for these functions is to have them be automatically-
|
||||||
// generated in the future.
|
// generated in the future.
|
||||||
|
|
||||||
|
template <>
|
||||||
|
const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpAccessGroup>() {
|
||||||
|
static const OmpModifierDescriptor desc{
|
||||||
|
/*name=*/"access-group",
|
||||||
|
/*props=*/
|
||||||
|
{
|
||||||
|
{61, {OmpProperty::Unique}},
|
||||||
|
},
|
||||||
|
/*clauses=*/
|
||||||
|
{
|
||||||
|
{61, {Clause::OMPC_dyn_groupprivate}},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpAlignment>() {
|
const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpAlignment>() {
|
||||||
static const OmpModifierDescriptor desc{
|
static const OmpModifierDescriptor desc{
|
||||||
@ -482,6 +498,9 @@ const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpPrescriptiveness>() {
|
|||||||
/*clauses=*/
|
/*clauses=*/
|
||||||
{
|
{
|
||||||
{51, {Clause::OMPC_grainsize, Clause::OMPC_num_tasks}},
|
{51, {Clause::OMPC_grainsize, Clause::OMPC_num_tasks}},
|
||||||
|
{61,
|
||||||
|
{Clause::OMPC_dyn_groupprivate, Clause::OMPC_grainsize,
|
||||||
|
Clause::OMPC_num_tasks}},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
return desc;
|
return desc;
|
||||||
|
47
flang/test/Semantics/OpenMP/prescriptiveness-modifier.f90
Normal file
47
flang/test/Semantics/OpenMP/prescriptiveness-modifier.f90
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=61
|
||||||
|
|
||||||
|
subroutine f00(x)
|
||||||
|
integer :: x, i
|
||||||
|
!No diagnostic expected
|
||||||
|
!$omp taskloop grainsize(strict: x)
|
||||||
|
do i = 1, 10
|
||||||
|
enddo
|
||||||
|
end
|
||||||
|
|
||||||
|
subroutine f01(x)
|
||||||
|
integer :: x, i
|
||||||
|
!ERROR: Only STRICT is allowed as prescriptiveness on this clause
|
||||||
|
!$omp taskloop grainsize(fallback: x)
|
||||||
|
do i = 1, 10
|
||||||
|
enddo
|
||||||
|
end
|
||||||
|
|
||||||
|
subroutine f02(x)
|
||||||
|
integer :: x, i
|
||||||
|
!No diagnostic expected
|
||||||
|
!$omp taskloop num_tasks(strict: x)
|
||||||
|
do i = 1, 10
|
||||||
|
enddo
|
||||||
|
end
|
||||||
|
|
||||||
|
subroutine f03(x)
|
||||||
|
integer :: x, i
|
||||||
|
!ERROR: Only STRICT is allowed as prescriptiveness on this clause
|
||||||
|
!$omp taskloop num_tasks(fallback: x)
|
||||||
|
do i = 1, 10
|
||||||
|
enddo
|
||||||
|
end
|
||||||
|
|
||||||
|
subroutine f04(x)
|
||||||
|
integer :: x
|
||||||
|
!No diagnostic expected
|
||||||
|
!$omp target dyn_groupprivate(strict: x)
|
||||||
|
!$omp end target
|
||||||
|
end
|
||||||
|
|
||||||
|
subroutine f05(x)
|
||||||
|
integer :: x
|
||||||
|
!No diagnostic expected
|
||||||
|
!$omp target dyn_groupprivate(fallback: x)
|
||||||
|
!$omp end target
|
||||||
|
end
|
Loading…
x
Reference in New Issue
Block a user