[OPENMP] Fix for http://llvm.org/PR23387: clang fails to compile magick/attribute.c
authorAlexey Bataev <a.bataev@hotmail.com>
Wed, 6 May 2015 06:34:55 +0000 (06:34 +0000)
committerAlexey Bataev <a.bataev@hotmail.com>
Wed, 6 May 2015 06:34:55 +0000 (06:34 +0000)
Allow to use variables with 'register' storage class as loop control variables in OpenMP loop based constructs.

llvm-svn: 236571

clang/lib/Sema/SemaOpenMP.cpp
clang/test/OpenMP/for_loop_messages.cpp

index fb3cd9a..4877d3f 100644 (file)
@@ -426,7 +426,8 @@ DSAStackTy::DSAVarData DSAStackTy::getTopDSA(VarDecl *D, bool FromParent) {
   // in a Construct, C/C++, predetermined, p.1]
   //  Variables appearing in threadprivate directives are threadprivate.
   if (D->getTLSKind() != VarDecl::TLS_None ||
-      D->getStorageClass() == SC_Register) {
+      (D->getStorageClass() == SC_Register && D->hasAttr<AsmLabelAttr>() &&
+       !D->isLocalVarDecl())) {
     DVar.CKind = OMPC_threadprivate;
     return DVar;
   }
@@ -885,7 +886,8 @@ Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
 
     // Check if this is a TLS variable.
     if (VD->getTLSKind() != VarDecl::TLS_None ||
-        VD->getStorageClass() == SC_Register) {
+        (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
+         !VD->isLocalVarDecl())) {
       Diag(ILoc, diag::err_omp_var_thread_local)
           << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
       bool IsDecl =
index 0b2fa9b..05b6430 100644 (file)
@@ -13,12 +13,15 @@ static int sii;
 #pragma omp threadprivate(sii) // expected-note {{defined as threadprivate or thread local}}
 static int globalii;
 
+register int reg0 __asm__("0"); // expected-note {{loop iteration variable is predetermined as linear}}
+
 int test_iteration_spaces() {
   const int N = 100;
   float a[N], b[N], c[N];
   int ii, jj, kk;
   float fii;
   double dii;
+  register int reg; // expected-warning {{'register' storage class specifier is deprecated}}
 #pragma omp parallel
 #pragma omp for
   for (int i = 0; i < 10; i += 1) {
@@ -313,6 +316,21 @@ int test_iteration_spaces() {
 
 #pragma omp parallel
   {
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp for' directive may not be threadprivate or thread local, predetermined as private}}
+#pragma omp for
+    for (reg0 = 0; reg0 < 10; reg0 += 1)
+      c[reg0] = a[reg0];
+  }
+
+#pragma omp parallel
+  {
+#pragma omp for
+    for (reg = 0; reg < 10; reg += 1)
+      c[reg] = a[reg];
+  }
+
+#pragma omp parallel
+  {
 #pragma omp for
     for (globalii = 0; globalii < 10; globalii += 1)
       c[globalii] = a[globalii];