[OPENMP] Temporary fix for processing of global variables in loops.
Currently there is a bug in processing of global variables used as loop control variables in 'omp for/simd' constructs: these globals must be captured as private variables, but currently they are nor. This is a temporary bug fix for this problem until the correct solution is prepared. If a global var used as lcv without explicit mark as a private/linear/lastprivate the error message is emitted.

llvm-svn: 221970
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4a528c4..8eb2757 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7195,6 +7195,8 @@
   "implicitly determined as %0">;
 def err_omp_loop_var_dsa : Error<
   "loop iteration variable in the associated loop of 'omp %1' directive may not be %0, predetermined as %2">;
+def err_omp_global_loop_var_dsa : Error<
+  "loop iteration variable in the associated loop of 'omp %1' directive may not be a variable with global storage without being explicitly marked as %0">;
 def err_omp_not_for : Error<
   "%select{statement after '#pragma omp %1' must be a for loop|"
   "expected %2 for loops after '#pragma omp %1'%select{|, but found only %4}3}0">;
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 5f03df4..9bdb092 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -2519,7 +2519,18 @@
     // Make the loop iteration variable private (for worksharing constructs),
     // linear (for simd directives with the only one associated loop) or
     // lastprivate (for simd directives with several collapsed loops).
-    DSA.addDSA(Var, LoopVarRefExpr, PredeterminedCKind);
+    // FIXME: the next check and error message must be removed once the
+    // capturing of global variables in loops is fixed.
+    if (DVar.CKind == OMPC_unknown)
+      DVar = DSA.hasDSA(Var, isOpenMPPrivate, MatchesAlways(),
+                        /*FromParent=*/false);
+    if (!Var->hasLocalStorage() && DVar.CKind == OMPC_unknown) {
+      SemaRef.Diag(Init->getLocStart(), diag::err_omp_global_loop_var_dsa)
+          << getOpenMPClauseName(PredeterminedCKind)
+          << getOpenMPDirectiveName(DKind);
+      HasErrors = true;
+    } else
+      DSA.addDSA(Var, LoopVarRefExpr, PredeterminedCKind);
   }
 
   assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
diff --git a/clang/test/OpenMP/for_loop_messages.cpp b/clang/test/OpenMP/for_loop_messages.cpp
index 37a5b2e..cb32484 100644
--- a/clang/test/OpenMP/for_loop_messages.cpp
+++ b/clang/test/OpenMP/for_loop_messages.cpp
@@ -11,6 +11,7 @@
 
 static int sii;
 #pragma omp threadprivate(sii) // expected-note {{defined as threadprivate or thread local}}
+static int globalii;
 
 int test_iteration_spaces() {
   const int N = 100;
@@ -311,6 +312,23 @@
   }
 
 #pragma omp parallel
+  {
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp for' directive may not be a variable with global storage without being explicitly marked as private}}
+#pragma omp for
+    for (globalii = 0; globalii < 10; globalii += 1)
+      c[globalii] = a[globalii];
+  }
+
+#pragma omp parallel
+  {
+// expected-error@+3 {{loop iteration variable in the associated loop of 'omp for' directive may not be a variable with global storage without being explicitly marked as private}}
+#pragma omp for collapse(2)
+    for (ii = 0; ii < 10; ii += 1)
+    for (globalii = 0; globalii < 10; globalii += 1)
+      c[globalii] += a[globalii] + ii;
+  }
+
+#pragma omp parallel
 // expected-error@+2 {{statement after '#pragma omp for' must be a for loop}}
 #pragma omp for
   for (auto &item : a) {
diff --git a/clang/test/OpenMP/for_simd_loop_messages.cpp b/clang/test/OpenMP/for_simd_loop_messages.cpp
index 05cf3ab..403709f 100644
--- a/clang/test/OpenMP/for_simd_loop_messages.cpp
+++ b/clang/test/OpenMP/for_simd_loop_messages.cpp
@@ -11,6 +11,7 @@
 
 static int sii;
 #pragma omp threadprivate(sii) // expected-note {{defined as threadprivate or thread local}}
+static int globalii;
 
 int test_iteration_spaces() {
   const int N = 100;
@@ -312,6 +313,23 @@
   }
 
 #pragma omp parallel
+  {
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp for simd' directive may not be a variable with global storage without being explicitly marked as linear}}
+#pragma omp for simd
+    for (globalii = 0; globalii < 10; globalii += 1)
+      c[globalii] = a[globalii];
+  }
+
+#pragma omp parallel
+  {
+// expected-error@+3 {{loop iteration variable in the associated loop of 'omp for simd' directive may not be a variable with global storage without being explicitly marked as lastprivate}}
+#pragma omp for simd collapse(2)
+    for (ii = 0; ii < 10; ii += 1)
+    for (globalii = 0; globalii < 10; globalii += 1)
+      c[globalii] += a[globalii] + ii;
+  }
+
+#pragma omp parallel
 // expected-error@+2 {{statement after '#pragma omp for simd' must be a for loop}}
 #pragma omp for simd
   for (auto &item : a) {
diff --git a/clang/test/OpenMP/parallel_for_loop_messages.cpp b/clang/test/OpenMP/parallel_for_loop_messages.cpp
index 791130d..c329997 100644
--- a/clang/test/OpenMP/parallel_for_loop_messages.cpp
+++ b/clang/test/OpenMP/parallel_for_loop_messages.cpp
@@ -11,6 +11,7 @@
 
 static int sii;
 #pragma omp threadprivate(sii) // expected-note {{defined as threadprivate or thread local}}
+static int globalii;
 
 int test_iteration_spaces() {
   const int N = 100;
@@ -263,6 +264,21 @@
       c[sii] = a[sii];
   }
 
+  {
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp parallel for' directive may not be a variable with global storage without being explicitly marked as private}}
+#pragma omp parallel for
+    for (globalii = 0; globalii < 10; globalii += 1)
+      c[globalii] = a[globalii];
+  }
+
+  {
+// expected-error@+3 {{loop iteration variable in the associated loop of 'omp parallel for' directive may not be a variable with global storage without being explicitly marked as private}}
+#pragma omp parallel for collapse(2)
+    for (ii = 0; ii < 10; ii += 1)
+    for (globalii = 0; globalii < 10; globalii += 1)
+      c[globalii] += a[globalii] + ii;
+  }
+
 // expected-error@+2 {{statement after '#pragma omp parallel for' must be a for loop}}
 #pragma omp parallel for
   for (auto &item : a) {
diff --git a/clang/test/OpenMP/parallel_for_simd_loop_messages.cpp b/clang/test/OpenMP/parallel_for_simd_loop_messages.cpp
index 0185fdd..50acb10 100644
--- a/clang/test/OpenMP/parallel_for_simd_loop_messages.cpp
+++ b/clang/test/OpenMP/parallel_for_simd_loop_messages.cpp
@@ -11,6 +11,7 @@
 
 static int sii;
 #pragma omp threadprivate(sii) // expected-note {{defined as threadprivate or thread local}}
+static int globalii;
 
 int test_iteration_spaces() {
   const int N = 100;
@@ -264,6 +265,21 @@
       c[sii] = a[sii];
   }
 
+  {
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp parallel for simd' directive may not be a variable with global storage without being explicitly marked as linear}}
+#pragma omp parallel for simd
+    for (globalii = 0; globalii < 10; globalii += 1)
+      c[globalii] = a[globalii];
+  }
+
+  {
+// expected-error@+3 {{loop iteration variable in the associated loop of 'omp parallel for simd' directive may not be a variable with global storage without being explicitly marked as lastprivate}}
+#pragma omp parallel for simd collapse(2)
+    for (ii = 0; ii < 10; ii += 1)
+    for (globalii = 0; globalii < 10; globalii += 1)
+      c[globalii] += a[globalii] + ii;
+  }
+
 // expected-error@+2 {{statement after '#pragma omp parallel for simd' must be a for loop}}
 #pragma omp parallel for simd
   for (auto &item : a) {
diff --git a/clang/test/OpenMP/simd_loop_messages.cpp b/clang/test/OpenMP/simd_loop_messages.cpp
index cdddeae..ce64842 100644
--- a/clang/test/OpenMP/simd_loop_messages.cpp
+++ b/clang/test/OpenMP/simd_loop_messages.cpp
@@ -2,6 +2,7 @@
 
 static int sii;
 #pragma omp threadprivate(sii) // expected-note {{defined as threadprivate or thread local}}
+static int globalii;
 
 int test_iteration_spaces() {
   const int N = 100;
@@ -257,6 +258,23 @@
       c[sii] = a[sii];
   }
 
+  #pragma omp parallel
+  {
+    // expected-error@+2 {{loop iteration variable in the associated loop of 'omp simd' directive may not be a variable with global storage without being explicitly marked as linear}}
+    #pragma omp simd
+    for (globalii = 0; globalii < 10; globalii+=1)
+      c[globalii] = a[globalii];
+  }
+
+  #pragma omp parallel
+  {
+// expected-error@+3 {{loop iteration variable in the associated loop of 'omp simd' directive may not be a variable with global storage without being explicitly marked as lastprivate}}
+#pragma omp simd collapse(2)
+    for (ii = 0; ii < 10; ii += 1)
+    for (globalii = 0; globalii < 10; globalii += 1)
+      c[globalii] += a[globalii] + ii;
+  }
+
   // expected-error@+2 {{statement after '#pragma omp simd' must be a for loop}}
   #pragma omp simd
   for (auto &item : a) {