summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2015-01-13 03:35:30 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2015-01-13 03:35:30 +0000
commitc4657ce15771243fda44de72d1f8fa6a25f76927 (patch)
tree0e404d36bdbd9a46830728290f29eeb6a05417bc
parent85f2b4c24c7b307e65000b79c020cade580f8e48 (diff)
[OPENMP] Consider global named register variables as threadprivate by default.
Register are thread-local by default, so we have to consider them as threadprivate. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@225759 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--lib/Sema/SemaOpenMP.cpp9
-rw-r--r--test/OpenMP/threadprivate_messages.cpp3
3 files changed, 10 insertions, 4 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 4bf83b6aed..8966c55d09 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7226,7 +7226,7 @@ def err_omp_var_scope : Error<
def err_omp_var_used : Error<
"'#pragma omp %0' must precede all references to variable %q1">;
def err_omp_var_thread_local : Error<
- "variable %0 cannot be threadprivate because it is thread-local">;
+ "variable %0 cannot be threadprivate because it is %select{thread-local|a global named register variable}1">;
def err_omp_private_incomplete_type : Error<
"a private variable with incomplete type %0">;
def err_omp_firstprivate_incomplete_type : Error<
diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp
index b00867dd30..d72942a2ff 100644
--- a/lib/Sema/SemaOpenMP.cpp
+++ b/lib/Sema/SemaOpenMP.cpp
@@ -391,7 +391,8 @@ DSAStackTy::DSAVarData DSAStackTy::getTopDSA(VarDecl *D, bool FromParent) {
// OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
// in a Construct, C/C++, predetermined, p.1]
// Variables appearing in threadprivate directives are threadprivate.
- if (D->getTLSKind() != VarDecl::TLS_None) {
+ if (D->getTLSKind() != VarDecl::TLS_None ||
+ D->getStorageClass() == SC_Register) {
DVar.CKind = OMPC_threadprivate;
return DVar;
}
@@ -841,8 +842,10 @@ Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
}
// Check if this is a TLS variable.
- if (VD->getTLSKind()) {
- Diag(ILoc, diag::err_omp_var_thread_local) << VD;
+ if (VD->getTLSKind() != VarDecl::TLS_None ||
+ VD->getStorageClass() == SC_Register) {
+ Diag(ILoc, diag::err_omp_var_thread_local)
+ << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
bool IsDecl =
VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
Diag(VD->getLocation(),
diff --git a/test/OpenMP/threadprivate_messages.cpp b/test/OpenMP/threadprivate_messages.cpp
index 491f30ad04..27b36fbe02 100644
--- a/test/OpenMP/threadprivate_messages.cpp
+++ b/test/OpenMP/threadprivate_messages.cpp
@@ -96,6 +96,9 @@ class TempClass {
static __thread int t; // expected-note {{'t' defined here}}
#pragma omp threadprivate (t) // expected-error {{variable 't' cannot be threadprivate because it is thread-local}}
+register int reg0 __asm__("0"); // expected-note {{'reg0' defined here}}
+#pragma omp threadprivate (reg0) // expected-error {{variable 'reg0' cannot be threadprivate because it is a global named register variable}}
+
int o; // expected-note {{candidate found by name lookup is 'o'}}
#pragma omp threadprivate (o)
namespace {