]> granicus.if.org Git - clang/commitdiff
[OPENMP]Fix PR39422: variables are not firstprivatized in task context.
authorAlexey Bataev <a.bataev@hotmail.com>
Thu, 25 Oct 2018 15:35:27 +0000 (15:35 +0000)
committerAlexey Bataev <a.bataev@hotmail.com>
Thu, 25 Oct 2018 15:35:27 +0000 (15:35 +0000)
According to the OpenMP standard, In a task generating construct, if no
default clause is present, a variable for which the data-sharing
attribute is not determined by the rules above is firstprivatized.
Compiler tries to implement this, but if the variable is not directly
used in the task context, this variable may not be firstprivatized.
Patch fixes this problem.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@345277 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaOpenMP.cpp
test/OpenMP/parallel_sections_default_messages.cpp
test/OpenMP/task_codegen.cpp

index 7b4cc9fd170e75d964315dcdeace4df42de75380..92d1514ee0c8aa6a25a4184d1b283b4b23590102 100644 (file)
@@ -2251,8 +2251,31 @@ public:
   }
   void VisitStmt(Stmt *S) {
     for (Stmt *C : S->children()) {
-      if (C && !isa<OMPExecutableDirective>(C))
-        Visit(C);
+      if (C) {
+        if (auto *OED = dyn_cast<OMPExecutableDirective>(C)) {
+          // Check implicitly captured vriables in the task-based directives to
+          // check if they must be firstprivatized.
+          if (!OED->hasAssociatedStmt())
+            continue;
+          const Stmt *AS = OED->getAssociatedStmt();
+          if (!AS)
+            continue;
+          for (const CapturedStmt::Capture &Cap :
+               cast<CapturedStmt>(AS)->captures()) {
+            if (Cap.capturesVariable()) {
+              DeclRefExpr *DRE = buildDeclRefExpr(
+                  SemaRef, Cap.getCapturedVar(),
+                  Cap.getCapturedVar()->getType().getNonLValueExprType(
+                      SemaRef.Context),
+                  Cap.getLocation(),
+                  /*RefersToCapture=*/true);
+              Visit(DRE);
+            }
+          }
+        } else {
+          Visit(C);
+        }
+      }
     }
   }
 
index a62b86ff34a8c6710796a75ec350683422f51537..b16e5f73695ed754ce3710eb767ac3b32104a02a 100644 (file)
@@ -34,7 +34,7 @@ int main(int argc, char **argv) {
   {
 #pragma omp parallel sections default(shared)
     {
-      ++argc;
+      ++argc;  // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
     }
   }
   return 0;
index 05767726f05a526abfa6408c1ae422ef1e8c2abe..b034bb29c8870926f20e61cc36915de7d77fffb0 100644 (file)
@@ -107,6 +107,7 @@ int main() {
 // CHECK: call i32 @__kmpc_omp_task([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]])
 #pragma omp task untied
   {
+#pragma omp critical
     a = 1;
   }
 // CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 0, i64 40, i64 1,