Skip to content

Commit f5d3470

Browse files
authored
[flang][OpenMP] Allow structure component in task depend clauses (#141923)
Even though the spec (version 5.2) prohibits strcuture components from being specified in `depend` clauses, this restriction is not sensible. This PR rectifies the issue by lifting that restriction and allowing structure components in `depend` clauses (which is allowed by OpenMP 6.0).
1 parent bfd7024 commit f5d3470

File tree

5 files changed

+38
-55
lines changed

5 files changed

+38
-55
lines changed

flang/include/flang/Evaluate/tools.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,16 @@ const Symbol *IsArrayElement(const Expr<T> &expr, bool intoSubstring = true,
414414
return nullptr;
415415
}
416416

417+
template <typename T>
418+
bool isStructureComponent(const Fortran::evaluate::Expr<T> &expr) {
419+
if (auto dataRef{ExtractDataRef(expr, /*intoSubstring=*/false)}) {
420+
const Fortran::evaluate::DataRef *ref{&*dataRef};
421+
return std::holds_alternative<Fortran::evaluate::Component>(ref->u);
422+
}
423+
424+
return false;
425+
}
426+
417427
template <typename A>
418428
std::optional<NamedEntity> ExtractNamedEntity(const A &x) {
419429
if (auto dataRef{ExtractDataRef(x)}) {

flang/lib/Lower/OpenMP/ClauseProcessor.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -947,6 +947,11 @@ bool ClauseProcessor::processDepend(lower::SymMap &symMap,
947947
converter.getCurrentLocation(), converter, expr, symMap, stmtCtx);
948948
dependVar = entity.getBase();
949949
}
950+
} else if (evaluate::isStructureComponent(*object.ref())) {
951+
SomeExpr expr = *object.ref();
952+
hlfir::EntityWithAttributes entity = convertExprToHLFIR(
953+
converter.getCurrentLocation(), converter, expr, symMap, stmtCtx);
954+
dependVar = entity.getBase();
950955
} else {
951956
semantics::Symbol *sym = object.sym();
952957
dependVar = converter.getSymbolAddress(*sym);

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

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5494,12 +5494,8 @@ void OmpStructureChecker::CheckDependList(const parser::DataRef &d) {
54945494
// Check if the base element is valid on Depend Clause
54955495
CheckDependList(elem.value().base);
54965496
},
5497-
[&](const common::Indirection<parser::StructureComponent> &) {
5498-
context_.Say(GetContext().clauseSource,
5499-
"A variable that is part of another variable "
5500-
"(such as an element of a structure) but is not an array "
5501-
"element or an array section cannot appear in a DEPEND "
5502-
"clause"_err_en_US);
5497+
[&](const common::Indirection<parser::StructureComponent> &comp) {
5498+
CheckDependList(comp.value().base);
55035499
},
55045500
[&](const common::Indirection<parser::CoindexedNamedObject> &) {
55055501
context_.Say(GetContext().clauseSource,
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
! RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s
2+
3+
subroutine depend
4+
type :: my_struct
5+
integer :: my_component(10)
6+
end type
7+
8+
type(my_struct) :: my_var
9+
10+
!$omp task depend(in:my_var%my_component)
11+
!$omp end task
12+
end subroutine depend
13+
14+
! CHECK: %[[VAR_ALLOC:.*]] = fir.alloca !fir.type<{{.*}}my_struct{{.*}}> {bindc_name = "my_var", {{.*}}}
15+
! CHECK: %[[VAR_DECL:.*]]:2 = hlfir.declare %[[VAR_ALLOC]]
16+
17+
! CHECK: %[[COMP_SELECTOR:.*]] = hlfir.designate %[[VAR_DECL]]#0{"my_component"}
18+
19+
! CHECK: omp.task depend(taskdependin -> %[[COMP_SELECTOR]] : {{.*}}) {
20+
! CHECK: omp.terminator
21+
! CHECK: }

flang/test/Semantics/OpenMP/depend02.f90

Lines changed: 0 additions & 49 deletions
This file was deleted.

0 commit comments

Comments
 (0)