summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2015-05-06 06:34:55 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2015-05-06 06:34:55 +0000
commit1a8b3f1a4eb406d9fc45f3a132f7969c10c76619 (patch)
tree7403de7ec2229508c33f31bc3618fa30ad785064
parent1d2854477c040b26232f7909f4575e190a3c13ba (diff)
downloadbcm5719-llvm-1a8b3f1a4eb406d9fc45f3a132f7969c10c76619.tar.gz
bcm5719-llvm-1a8b3f1a4eb406d9fc45f3a132f7969c10c76619.zip
[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
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp6
-rw-r--r--clang/test/OpenMP/for_loop_messages.cpp18
2 files changed, 22 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index fb3cd9a4f92..4877d3f55fc 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<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 =
diff --git a/clang/test/OpenMP/for_loop_messages.cpp b/clang/test/OpenMP/for_loop_messages.cpp
index 0b2fa9bbc17..05b643027ae 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];
OpenPOWER on IntegriCloud