[llvm-branch-commits] [flang] a2ca6bb - [Flang][OpenMP] Add semantic check for OpenMP Private, Firstprivate and Lastprivate clauses.
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Dec 25 01:25:57 PST 2020
Author: Praveen
Date: 2020-12-25T14:43:41+05:30
New Revision: a2ca6bbda6160c1b474fffd6204bcac9456c7eb1
URL: https://github.com/llvm/llvm-project/commit/a2ca6bbda6160c1b474fffd6204bcac9456c7eb1
DIFF: https://github.com/llvm/llvm-project/commit/a2ca6bbda6160c1b474fffd6204bcac9456c7eb1.diff
LOG: [Flang][OpenMP] Add semantic check for OpenMP Private, Firstprivate and Lastprivate clauses.
OpenMP 4.5 - Variables that appear in expressions for statement function definitions
may not appear in OpenMP Private, Firstprivate or Lastprivate clauses.
Test case : omp-private03.f90
Reviewed By: kiranchandramohan
Differential Revision: https://reviews.llvm.org/D93213
Added:
flang/test/Semantics/omp-private03.f90
Modified:
flang/lib/Semantics/resolve-directives.cpp
Removed:
################################################################################
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index a4297ab42540..e10d797d0308 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -232,6 +232,18 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
return true;
}
+ bool Pre(const parser::StmtFunctionStmt &x) {
+ const auto &parsedExpr{std::get<parser::Scalar<parser::Expr>>(x.t)};
+ if (const auto *expr{GetExpr(parsedExpr)}) {
+ for (const Symbol &symbol : evaluate::CollectSymbols(*expr)) {
+ if (!IsStmtFunctionDummy(symbol)) {
+ stmtFunctionExprSymbols_.insert(symbol.GetUltimate());
+ }
+ }
+ }
+ return true;
+ }
+
bool Pre(const parser::OpenMPBlockConstruct &);
void Post(const parser::OpenMPBlockConstruct &);
@@ -342,6 +354,7 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
std::vector<const parser::Name *> allocateNames_; // on one directive
SymbolSet privateDataSharingAttributeObjects_; // on one directive
+ SymbolSet stmtFunctionExprSymbols_;
void AddAllocateName(const parser::Name *&object) {
allocateNames_.push_back(object);
@@ -377,7 +390,7 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
const parser::Name &, const Symbol &, Symbol::Flag);
void CheckAssocLoopLevel(std::int64_t level, const parser::OmpClause *clause);
- void CheckObjectInNamelist(
+ void CheckPrivateDSAObject(
const parser::Name &, const Symbol &, Symbol::Flag);
};
@@ -1163,7 +1176,7 @@ void OmpAttributeVisitor::ResolveOmpObject(
CheckMultipleAppearances(*name, *symbol, ompFlag);
}
if (privateDataSharingAttributeFlags.test(ompFlag)) {
- CheckObjectInNamelist(*name, *symbol, ompFlag);
+ CheckPrivateDSAObject(*name, *symbol, ompFlag);
}
if (ompFlag == Symbol::Flag::OmpAllocate) {
@@ -1317,18 +1330,28 @@ void OmpAttributeVisitor::CheckDataCopyingClause(
}
}
-void OmpAttributeVisitor::CheckObjectInNamelist(
+void OmpAttributeVisitor::CheckPrivateDSAObject(
const parser::Name &name, const Symbol &symbol, Symbol::Flag ompFlag) {
- if (symbol.GetUltimate().test(Symbol::Flag::InNamelist)) {
- llvm::StringRef clauseName{"PRIVATE"};
- if (ompFlag == Symbol::Flag::OmpFirstPrivate)
- clauseName = "FIRSTPRIVATE";
- else if (ompFlag == Symbol::Flag::OmpLastPrivate)
- clauseName = "LASTPRIVATE";
+ const auto &ultimateSymbol{symbol.GetUltimate()};
+ llvm::StringRef clauseName{"PRIVATE"};
+ if (ompFlag == Symbol::Flag::OmpFirstPrivate)
+ clauseName = "FIRSTPRIVATE";
+ else if (ompFlag == Symbol::Flag::OmpLastPrivate)
+ clauseName = "LASTPRIVATE";
+
+ if (ultimateSymbol.test(Symbol::Flag::InNamelist)) {
context_.Say(name.source,
"Variable '%s' in NAMELIST cannot be in a %s clause"_err_en_US,
name.ToString(), clauseName.str());
}
+
+ if (stmtFunctionExprSymbols_.find(ultimateSymbol) !=
+ stmtFunctionExprSymbols_.end()) {
+ context_.Say(name.source,
+ "Variable '%s' in STATEMENT FUNCTION expression cannot be in a "
+ "%s clause"_err_en_US,
+ name.ToString(), clauseName.str());
+ }
}
} // namespace Fortran::semantics
diff --git a/flang/test/Semantics/omp-private03.f90 b/flang/test/Semantics/omp-private03.f90
new file mode 100644
index 000000000000..50748f5508ed
--- /dev/null
+++ b/flang/test/Semantics/omp-private03.f90
@@ -0,0 +1,39 @@
+! RUN: %S/test_errors.sh %s %t %f18 -fopenmp
+! OpenMP Version 4.5
+! Variables that appear in expressions for statement function definitions
+! may not appear in private, firstprivate or lastprivate clauses.
+
+subroutine stmt_function(temp)
+
+ integer :: i, p, q, r
+ real :: c, f, s, v, t(10)
+ real, intent(in) :: temp
+
+ c(temp) = p * (temp - q) / r
+ f(temp) = q + (temp * r/p)
+ v(temp) = c(temp) + f(temp)/2 - s
+
+ p = 5
+ q = 32
+ r = 9
+
+ !ERROR: Variable 'p' in STATEMENT FUNCTION expression cannot be in a PRIVATE clause
+ !$omp parallel private(p)
+ s = c(temp)
+ !$omp end parallel
+
+ !ERROR: Variable 's' in STATEMENT FUNCTION expression cannot be in a FIRSTPRIVATE clause
+ !$omp parallel firstprivate(s)
+ s = s + f(temp)
+ !$omp end parallel
+
+ !ERROR: Variable 's' in STATEMENT FUNCTION expression cannot be in a LASTPRIVATE clause
+ !$omp parallel do lastprivate(s, t)
+ do i = 1, 10
+ t(i) = v(temp) + i - s
+ end do
+ !$omp end parallel do
+
+ print *, t
+
+end subroutine stmt_function
More information about the llvm-branch-commits
mailing list