From 1a8b3f1a4eb406d9fc45f3a132f7969c10c76619 Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Wed, 6 May 2015 06:34:55 +0000 Subject: [PATCH] [OPENMP] Fix for http://llvm.org/PR23387: clang fails to compile magick/attribute.c 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 | 6 ++++-- clang/test/OpenMP/for_loop_messages.cpp | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index fb3cd9a..4877d3f 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -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() && + !D->isLocalVarDecl())) { DVar.CKind = OMPC_threadprivate; return DVar; } @@ -885,7 +886,8 @@ Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef VarList) { // Check if this is a TLS variable. if (VD->getTLSKind() != VarDecl::TLS_None || - VD->getStorageClass() == SC_Register) { + (VD->getStorageClass() == SC_Register && VD->hasAttr() && + !VD->isLocalVarDecl())) { Diag(ILoc, diag::err_omp_var_thread_local) << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); bool IsDecl = diff --git a/clang/test/OpenMP/for_loop_messages.cpp b/clang/test/OpenMP/for_loop_messages.cpp index 0b2fa9b..05b6430 100644 --- a/clang/test/OpenMP/for_loop_messages.cpp +++ b/clang/test/OpenMP/for_loop_messages.cpp @@ -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]; -- 2.7.4