diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -15119,6 +15119,17 @@ continue; } } + } else { + // Threadprivates cannot be shared between threads, so dignose if the base + // is a threadprivate variable. + DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); + if (DVar.CKind == OMPC_threadprivate) { + S.Diag(ELoc, diag::err_omp_wrong_dsa) + << getOpenMPClauseName(DVar.CKind) + << getOpenMPClauseName(OMPC_reduction); + reportOriginalDsa(S, Stack, D, DVar); + continue; + } } // Try to find 'declare reduction' corresponding construct before using diff --git a/clang/test/OpenMP/parallel_reduction_messages.cpp b/clang/test/OpenMP/parallel_reduction_messages.cpp --- a/clang/test/OpenMP/parallel_reduction_messages.cpp +++ b/clang/test/OpenMP/parallel_reduction_messages.cpp @@ -92,6 +92,8 @@ S3 h, k; #pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}} +int *gptr; +#pragma omp threadprivate(gptr) // expected-note {{defined as threadprivate or thread local}} template // expected-note {{declared here}} T tmain(T argc) { @@ -277,6 +279,8 @@ m++; #pragma omp parallel reduction(task, + : m) // omp45-error 2 {{expected expression}} omp45-warning {{missing ':' after reduction identifier - ignoring}} m++; +#pragma omp parallel reduction(+:gptr[:argc]) // expected-error {{threadprivate or thread local variable cannot be reduction}} + ; return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain' requested here}} expected-note {{in instantiation of function template specialization 'tmain' requested here}} }