Skip to content

Commit 91e6dee

Browse files
authored
[Flang][OpenMP] Improve Semantics for Derived Type Array Elements (llvm#167296)
Flang does not allow the use of Structure Component types inside of certain OpenMP clauses. While this has been introduced, it seemed that Structure Component Array Elements were not being captured as they got embedded in the parse tree. To ensure all structure component types are identified, a new `HasStructureComponent` evaluate function has been introduced to walk a Semantics expression, identified where Components are used within. This replaces the previous implementation of `CheckStructureComponent` which just looked for the StructureComponent inside of a DataRef. Fixes llvm#150830
1 parent 7894a57 commit 91e6dee

File tree

7 files changed

+46
-3
lines changed

7 files changed

+46
-3
lines changed

flang/include/flang/Evaluate/tools.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,6 +1110,9 @@ bool IsArraySection(const Expr<SomeType> &expr);
11101110
// Predicate: does an expression contain constant?
11111111
bool HasConstant(const Expr<SomeType> &);
11121112

1113+
// Predicate: Does an expression contain a component
1114+
bool HasStructureComponent(const Expr<SomeType> &expr);
1115+
11131116
// Utilities for attaching the location of the declaration of a symbol
11141117
// of interest to a message. Handles the case of USE association gracefully.
11151118
parser::Message *AttachDeclaration(parser::Message &, const Symbol &);

flang/lib/Evaluate/tools.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,6 +1210,20 @@ bool HasConstant(const Expr<SomeType> &expr) {
12101210
return HasConstantHelper{}(expr);
12111211
}
12121212

1213+
// HasStructureComponent()
1214+
struct HasStructureComponentHelper
1215+
: public AnyTraverse<HasStructureComponentHelper, bool, false> {
1216+
using Base = AnyTraverse<HasStructureComponentHelper, bool, false>;
1217+
HasStructureComponentHelper() : Base(*this) {}
1218+
using Base::operator();
1219+
1220+
bool operator()(const Component &) const { return true; }
1221+
};
1222+
1223+
bool HasStructureComponent(const Expr<SomeType> &expr) {
1224+
return HasStructureComponentHelper{}(expr);
1225+
}
1226+
12131227
parser::Message *AttachDeclaration(
12141228
parser::Message &message, const Symbol &symbol) {
12151229
const Symbol *unhosted{&symbol};

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4673,10 +4673,12 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Copyin &x) {
46734673
void OmpStructureChecker::CheckStructureComponent(
46744674
const parser::OmpObjectList &objects, llvm::omp::Clause clauseId) {
46754675
auto CheckComponent{[&](const parser::Designator &designator) {
4676-
if (auto *dataRef{std::get_if<parser::DataRef>(&designator.u)}) {
4676+
if (const parser::DataRef *dataRef{
4677+
std::get_if<parser::DataRef>(&designator.u)}) {
46774678
if (!IsDataRefTypeParamInquiry(dataRef)) {
4678-
if (auto *comp{parser::Unwrap<parser::StructureComponent>(*dataRef)}) {
4679-
context_.Say(comp->component.source,
4679+
const auto expr{AnalyzeExpr(context_, designator)};
4680+
if (expr.has_value() && evaluate::HasStructureComponent(expr.value())) {
4681+
context_.Say(designator.source,
46804682
"A variable that is part of another variable cannot appear on the %s clause"_err_en_US,
46814683
parser::ToUpperCaseLetters(getClauseName(clauseId).str()));
46824684
}

flang/test/Semantics/OpenMP/in-reduction.f90

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ subroutine f06
4747
integer :: a(10)
4848
end type
4949
type(t) :: x
50+
!ERROR: A variable that is part of another variable cannot appear on the IN_REDUCTION clause
5051
!ERROR: The base expression of an array element or section in IN_REDUCTION clause must be an identifier
5152
!$omp target in_reduction(+: x%a(2))
5253
!$omp end target
@@ -57,6 +58,7 @@ subroutine f07
5758
integer :: a(10)
5859
end type
5960
type(t) :: x
61+
!ERROR: A variable that is part of another variable cannot appear on the IN_REDUCTION clause
6062
!ERROR: The base expression of an array element or section in IN_REDUCTION clause must be an identifier
6163
!$omp target in_reduction(+: x%a(1:10))
6264
!$omp end target

flang/test/Semantics/OpenMP/reduction15.f90

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ module m
1313

1414
subroutine f00
1515
type(t) :: x
16+
!ERROR: A variable that is part of another variable cannot appear on the REDUCTION clause
1617
!ERROR: The base expression of an array element or section in REDUCTION clause must be an identifier
1718
!$omp do reduction (+ : x%a(2))
1819
do i = 1, 10
@@ -22,6 +23,7 @@ subroutine f00
2223

2324
subroutine f01
2425
type(t) :: x
26+
!ERROR: A variable that is part of another variable cannot appear on the REDUCTION clause
2527
!ERROR: The base expression of an array element or section in REDUCTION clause must be an identifier
2628
!$omp do reduction (+ : x%a(1:10))
2729
do i = 1, 10
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
! Test that Structure Component Array Elements are caught by Semantics and return an error
2+
! RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp -fopenmp-version=45
3+
4+
type test_type
5+
integer :: array(2)
6+
end type
7+
8+
contains
9+
subroutine test
10+
type(test_type) :: x
11+
12+
!ERROR: A variable that is part of another variable cannot appear on the REDUCTION clause
13+
!$omp do reduction(+: x%array(2))
14+
do i=1, 2
15+
end do
16+
!$omp end do
17+
end subroutine
18+
end

flang/test/Semantics/OpenMP/task-reduction.f90

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ subroutine f06
4747
integer :: a(10)
4848
end type
4949
type(t) :: x
50+
!ERROR: A variable that is part of another variable cannot appear on the TASK_REDUCTION clause
5051
!ERROR: The base expression of an array element or section in TASK_REDUCTION clause must be an identifier
5152
!$omp taskgroup task_reduction(+: x%a(2))
5253
!$omp end taskgroup
@@ -57,6 +58,7 @@ subroutine f07
5758
integer :: a(10)
5859
end type
5960
type(t) :: x
61+
!ERROR: A variable that is part of another variable cannot appear on the TASK_REDUCTION clause
6062
!ERROR: The base expression of an array element or section in TASK_REDUCTION clause must be an identifier
6163
!$omp taskgroup task_reduction(+: x%a(1:10))
6264
!$omp end taskgroup

0 commit comments

Comments
 (0)