Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions flang/lib/Semantics/check-omp-structure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,23 @@ class OmpWorkshareBlockChecker {
if (const auto *e{GetExpr(context_, expr)}) {
for (const Symbol &symbol : evaluate::CollectSymbols(*e)) {
const Symbol &root{GetAssociationRoot(symbol)};
if (IsFunction(root) && !IsElementalProcedure(root)) {
context_.Say(expr.source,
"User defined non-ELEMENTAL function "
"'%s' is not allowed in a WORKSHARE construct"_err_en_US,
root.name());
if (IsFunction(root)) {
std::string attrs{""};
if (!IsElementalProcedure(root)) {
attrs = " non-ELEMENTAL";
}
if (root.attrs().test(Attr::IMPURE)) {
if (attrs != "") {
attrs = "," + attrs;
}
attrs = " IMPURE" + attrs;
}
if (attrs != "") {
context_.Say(expr.source,
"User defined%s function '%s' is not allowed in a "
"WORKSHARE construct"_err_en_US,
attrs, root.name());
}
}
}
}
Expand Down
18 changes: 18 additions & 0 deletions flang/test/Semantics/OpenMP/workshare02.f90
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ module my_mod
integer function my_func()
my_func = 10
end function my_func

impure integer function impure_my_func()
impure_my_func = 20
end function impure_my_func

impure elemental integer function impure_ele_my_func()
impure_ele_my_func = 20
end function impure_ele_my_func
end module my_mod

subroutine workshare(aa, bb, cc, dd, ee, ff, n)
Expand Down Expand Up @@ -61,6 +69,16 @@ subroutine workshare(aa, bb, cc, dd, ee, ff, n)
j = j - my_func()
!$omp end atomic

!ERROR: User defined IMPURE, non-ELEMENTAL function 'impure_my_func' is not allowed in a WORKSHARE construct
cc = impure_my_func()
!ERROR: User defined IMPURE function 'impure_ele_my_func' is not allowed in a WORKSHARE construct
aa(1) = impure_ele_my_func()

!$omp end workshare

!$omp workshare
j = j + 1
!ERROR: At most one NOWAIT clause can appear on the END WORKSHARE directive
!$omp end workshare nowait nowait

end subroutine workshare
2 changes: 1 addition & 1 deletion llvm/include/llvm/Frontend/OpenMP/OMP.td
Original file line number Diff line number Diff line change
Expand Up @@ -1170,7 +1170,7 @@ def OMP_Workshare : Directive<"workshare"> {
let category = CA_Executable;
}
def OMP_EndWorkshare : Directive<"end workshare"> {
let allowedClauses = [
let allowedOnceClauses = [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: please could you add a test for this check as well. Something in flang/test/ is okay

Otherwise this LGTM

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh my mistake

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues, @tblah. Thanks for the review!

VersionedClause<OMPC_NoWait>,
];
let leafConstructs = OMP_Workshare.leafConstructs;
Expand Down