smateo created this revision.
smateo added a reviewer: ABataev.
smateo added a project: OpenMP.
Herald added a subscriber: cfe-commits.

There is a minor issue in how the implicit data-sharings for nested tasks are 
computed.

For the following example:

  int x;
  #pragma omp task shared(x)
  #pragma omp task
  x++;

We compute an implicit data-sharing of shared for `x` in the second task 
although I think that it should be firstprivate. Below you can find the part of 
the OpenMP spec that covers this example:

- // 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 and that in the enclosing context is determined to be shared by all 
implicit tasks bound to the current team is shared.//
- //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 
firstprivate.//

Since each implicit-task has its own copy of `x`, we shouldn't apply the first 
rule.


Repository:
  rC Clang

https://reviews.llvm.org/D56430

Files:
  lib/Sema/SemaOpenMP.cpp
  test/OpenMP/task_messages.cpp


Index: test/OpenMP/task_messages.cpp
===================================================================
--- test/OpenMP/task_messages.cpp
+++ test/OpenMP/task_messages.cpp
@@ -8,7 +8,7 @@
 #pragma omp task // expected-error {{unexpected OpenMP directive '#pragma omp 
task'}}
 
 class S {
-  S(const S &s) { a = s.a + 12; } // expected-note 14 {{implicitly declared 
private here}}
+  S(const S &s) { a = s.a + 12; } // expected-note 16 {{implicitly declared 
private here}}
   int a;
 
 public:
@@ -51,6 +51,15 @@
   ++a; // expected-error {{calling a private constructor of class 'S'}}
 #pragma omp task default(shared)
 #pragma omp task
+  // expected-error@+1 {{calling a private constructor of class 'S'}}
+  ++a;
+#pragma omp parallel shared(a)
+#pragma omp task
+#pragma omp task
+  ++a;
+#pragma omp parallel shared(a)
+#pragma omp task default(shared)
+#pragma omp task
   ++a;
 #pragma omp task
 #pragma omp parallel
@@ -205,6 +214,15 @@
   ++sa; // expected-error {{calling a private constructor of class 'S'}}
 #pragma omp task default(shared)
 #pragma omp task
+  // expected-error@+1 {{calling a private constructor of class 'S'}}
+  ++sa;
+#pragma omp parallel shared(sa)
+#pragma omp task
+#pragma omp task
+  ++sa;
+#pragma omp parallel shared(sa)
+#pragma omp task default(shared)
+#pragma omp task
   ++sa;
 #pragma omp task
 #pragma omp parallel
Index: lib/Sema/SemaOpenMP.cpp
===================================================================
--- lib/Sema/SemaOpenMP.cpp
+++ lib/Sema/SemaOpenMP.cpp
@@ -676,9 +676,13 @@
   }
 
 };
+
+bool isParallelRegion(OpenMPDirectiveKind DKind) {
+  return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
+}
+
 bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) {
-  return isOpenMPParallelDirective(DKind) || isOpenMPTaskingDirective(DKind) ||
-         isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown;
+  return isParallelRegion(DKind) || isOpenMPTaskingDirective(DKind) || DKind 
== OMPD_unknown;
 }
 
 } // namespace
@@ -819,7 +823,7 @@
           DVar.CKind = OMPC_firstprivate;
           return DVar;
         }
-      } while (I != E && !isParallelOrTaskRegion(I->Directive));
+      } while (I != E && !isParallelRegion(I->Directive));
       DVar.CKind =
           (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
       return DVar;


Index: test/OpenMP/task_messages.cpp
===================================================================
--- test/OpenMP/task_messages.cpp
+++ test/OpenMP/task_messages.cpp
@@ -8,7 +8,7 @@
 #pragma omp task // expected-error {{unexpected OpenMP directive '#pragma omp task'}}
 
 class S {
-  S(const S &s) { a = s.a + 12; } // expected-note 14 {{implicitly declared private here}}
+  S(const S &s) { a = s.a + 12; } // expected-note 16 {{implicitly declared private here}}
   int a;
 
 public:
@@ -51,6 +51,15 @@
   ++a; // expected-error {{calling a private constructor of class 'S'}}
 #pragma omp task default(shared)
 #pragma omp task
+  // expected-error@+1 {{calling a private constructor of class 'S'}}
+  ++a;
+#pragma omp parallel shared(a)
+#pragma omp task
+#pragma omp task
+  ++a;
+#pragma omp parallel shared(a)
+#pragma omp task default(shared)
+#pragma omp task
   ++a;
 #pragma omp task
 #pragma omp parallel
@@ -205,6 +214,15 @@
   ++sa; // expected-error {{calling a private constructor of class 'S'}}
 #pragma omp task default(shared)
 #pragma omp task
+  // expected-error@+1 {{calling a private constructor of class 'S'}}
+  ++sa;
+#pragma omp parallel shared(sa)
+#pragma omp task
+#pragma omp task
+  ++sa;
+#pragma omp parallel shared(sa)
+#pragma omp task default(shared)
+#pragma omp task
   ++sa;
 #pragma omp task
 #pragma omp parallel
Index: lib/Sema/SemaOpenMP.cpp
===================================================================
--- lib/Sema/SemaOpenMP.cpp
+++ lib/Sema/SemaOpenMP.cpp
@@ -676,9 +676,13 @@
   }
 
 };
+
+bool isParallelRegion(OpenMPDirectiveKind DKind) {
+  return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
+}
+
 bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) {
-  return isOpenMPParallelDirective(DKind) || isOpenMPTaskingDirective(DKind) ||
-         isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown;
+  return isParallelRegion(DKind) || isOpenMPTaskingDirective(DKind) || DKind == OMPD_unknown;
 }
 
 } // namespace
@@ -819,7 +823,7 @@
           DVar.CKind = OMPC_firstprivate;
           return DVar;
         }
-      } while (I != E && !isParallelOrTaskRegion(I->Directive));
+      } while (I != E && !isParallelRegion(I->Directive));
       DVar.CKind =
           (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
       return DVar;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to