[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