From 24b04aa393d683404aec0e77a5d3915ed8f65eb0 Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Fri, 16 Jan 2015 07:11:33 +0000 Subject: [PATCH] [OPENMP] Fixed data-sharing attributes processing for variables with global storage. This fix allows to use non-constant global variables, static local variables and static data members in data-sharing attribute clauses in parallel and task regions. llvm-svn: 226250 --- clang/lib/Sema/SemaOpenMP.cpp | 35 ++++++++----------- .../parallel_for_lastprivate_messages.cpp | 4 +-- .../parallel_for_reduction_messages.cpp | 6 ++-- ...parallel_for_simd_lastprivate_messages.cpp | 4 +-- .../parallel_for_simd_reduction_messages.cpp | 6 ++-- .../test/OpenMP/parallel_private_messages.cpp | 4 +-- .../OpenMP/parallel_reduction_messages.cpp | 6 ++-- ...parallel_sections_lastprivate_messages.cpp | 4 +-- .../parallel_sections_reduction_messages.cpp | 6 ++-- clang/test/OpenMP/task_private_messages.cpp | 4 +-- clang/test/OpenMP/teams_private_messages.cpp | 4 +-- .../test/OpenMP/teams_reduction_messages.cpp | 6 ++-- 12 files changed, 41 insertions(+), 48 deletions(-) diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index d72942a2ffec..0d349068860b 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -421,21 +421,23 @@ DSAStackTy::DSAVarData DSAStackTy::getTopDSA(VarDecl *D, bool FromParent) { DVar.CKind = OMPC_private; return DVar; } - } - // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced - // in a Construct, C/C++, predetermined, p.4] - // Static data members are shared. - if (D->isStaticDataMember()) { - // Variables with const-qualified type having no mutable member may be - // listed in a firstprivate clause, even if they are static data members. - DSAVarData DVarTemp = hasDSA(D, MatchesAnyClause(OMPC_firstprivate), - MatchesAlways(), FromParent); - if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr) + // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced + // in a Construct, C/C++, predetermined, p.4] + // Static data members are shared. + if (D->isStaticDataMember()) { + DVar.CKind = OMPC_shared; return DVar; + } - DVar.CKind = OMPC_shared; - return DVar; + // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced + // in a Construct, C/C++, predetermined, p.7] + // Variables with static storage duration that are declared in a scope + // inside the construct are shared. + if (D->isStaticLocal()) { + DVar.CKind = OMPC_shared; + return DVar; + } } QualType Type = D->getType().getNonReferenceType().getCanonicalType(); @@ -463,15 +465,6 @@ DSAStackTy::DSAVarData DSAStackTy::getTopDSA(VarDecl *D, bool FromParent) { return DVar; } - // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced - // in a Construct, C/C++, predetermined, p.7] - // Variables with static storage duration that are declared in a scope - // inside the construct are shared. - if (D->isStaticLocal()) { - DVar.CKind = OMPC_shared; - return DVar; - } - // Explicitly specified attributes and local variables with predetermined // attributes. auto I = std::prev(StartI); diff --git a/clang/test/OpenMP/parallel_for_lastprivate_messages.cpp b/clang/test/OpenMP/parallel_for_lastprivate_messages.cpp index bd1dd4b52768..915cbf7c230a 100644 --- a/clang/test/OpenMP/parallel_for_lastprivate_messages.cpp +++ b/clang/test/OpenMP/parallel_for_lastprivate_messages.cpp @@ -15,7 +15,7 @@ class S2 { public: S2() : a(0) {} S2(S2 &s2) : a(s2.a) {} - static float S2s; // expected-note {{static data member is predetermined as shared}} + static float S2s; static const float S2sc; }; const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}} @@ -181,7 +181,7 @@ int main(int argc, char **argv) { #pragma omp parallel for lastprivate(xa) // OK for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}} +#pragma omp parallel for lastprivate(S2::S2s) for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}} diff --git a/clang/test/OpenMP/parallel_for_reduction_messages.cpp b/clang/test/OpenMP/parallel_for_reduction_messages.cpp index 8e482ef73536..676b86fa5940 100644 --- a/clang/test/OpenMP/parallel_for_reduction_messages.cpp +++ b/clang/test/OpenMP/parallel_for_reduction_messages.cpp @@ -16,7 +16,7 @@ class S2 { public: S2() : a(0) {} S2(S2 &s2) : a(s2.a) {} - static float S2s; // expected-note 2 {{static data member is predetermined as shared}} + static float S2s; static const float S2sc; }; const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}} @@ -135,7 +135,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} #pragma omp parallel for reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} +#pragma omp parallel for reduction(&& : S2::S2s) for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} @@ -249,7 +249,7 @@ int main(int argc, char **argv) { #pragma omp parallel for reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} +#pragma omp parallel for reduction(&& : S2::S2s) for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} diff --git a/clang/test/OpenMP/parallel_for_simd_lastprivate_messages.cpp b/clang/test/OpenMP/parallel_for_simd_lastprivate_messages.cpp index b620c7fc010b..3d53259e8566 100644 --- a/clang/test/OpenMP/parallel_for_simd_lastprivate_messages.cpp +++ b/clang/test/OpenMP/parallel_for_simd_lastprivate_messages.cpp @@ -15,7 +15,7 @@ class S2 { public: S2() : a(0) {} S2(S2 &s2) : a(s2.a) {} - static float S2s; // expected-note {{static data member is predetermined as shared}} + static float S2s; static const float S2sc; }; const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}} @@ -181,7 +181,7 @@ int main(int argc, char **argv) { #pragma omp parallel for simd lastprivate(xa) // OK for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for simd lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}} +#pragma omp parallel for simd lastprivate(S2::S2s) for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for simd lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}} diff --git a/clang/test/OpenMP/parallel_for_simd_reduction_messages.cpp b/clang/test/OpenMP/parallel_for_simd_reduction_messages.cpp index 61690ddd42c1..2395cbd686f9 100644 --- a/clang/test/OpenMP/parallel_for_simd_reduction_messages.cpp +++ b/clang/test/OpenMP/parallel_for_simd_reduction_messages.cpp @@ -16,7 +16,7 @@ class S2 { public: S2() : a(0) {} S2(S2 &s2) : a(s2.a) {} - static float S2s; // expected-note 2 {{static data member is predetermined as shared}} + static float S2s; static const float S2sc; }; const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}} @@ -135,7 +135,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} #pragma omp parallel for simd reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} +#pragma omp parallel for simd reduction(&& : S2::S2s) for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} @@ -249,7 +249,7 @@ int main(int argc, char **argv) { #pragma omp parallel for simd reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} +#pragma omp parallel for simd reduction(&& : S2::S2s) for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} diff --git a/clang/test/OpenMP/parallel_private_messages.cpp b/clang/test/OpenMP/parallel_private_messages.cpp index 14c5cbdb8aea..74949ba3434e 100644 --- a/clang/test/OpenMP/parallel_private_messages.cpp +++ b/clang/test/OpenMP/parallel_private_messages.cpp @@ -13,7 +13,7 @@ class S2 { mutable int a; public: S2():a(0) { } - static float S2s; // expected-note {{static data member is predetermined as shared}} + static float S2s; }; const S2 b; const S2 ba[5]; @@ -61,7 +61,7 @@ int main(int argc, char **argv) { #pragma omp parallel private(ba) #pragma omp parallel private(ca) // expected-error {{shared variable cannot be private}} #pragma omp parallel private(da) // expected-error {{shared variable cannot be private}} - #pragma omp parallel private(S2::S2s) // expected-error {{shared variable cannot be private}} + #pragma omp parallel private(S2::S2s) #pragma omp parallel private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} #pragma omp parallel private(threadvar) // expected-error {{threadprivate or thread local variable cannot be private}} #pragma omp parallel shared(i), private(i) // expected-error {{shared variable cannot be private}} expected-note {{defined as shared}} diff --git a/clang/test/OpenMP/parallel_reduction_messages.cpp b/clang/test/OpenMP/parallel_reduction_messages.cpp index 43ebc01b2a36..46bc7a58a8be 100644 --- a/clang/test/OpenMP/parallel_reduction_messages.cpp +++ b/clang/test/OpenMP/parallel_reduction_messages.cpp @@ -16,7 +16,7 @@ class S2 { public: S2() : a(0) {} S2(S2 &s2) : a(s2.a) {} - static float S2s; // expected-note 2 {{static data member is predetermined as shared}} + static float S2s; static const float S2sc; }; const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}} @@ -115,7 +115,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} foo(); #pragma omp parallel reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}} foo(); -#pragma omp parallel reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} +#pragma omp parallel reduction(&& : S2::S2s) foo(); #pragma omp parallel reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} foo(); @@ -202,7 +202,7 @@ int main(int argc, char **argv) { foo(); #pragma omp parallel reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}} foo(); -#pragma omp parallel reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} +#pragma omp parallel reduction(&& : S2::S2s) foo(); #pragma omp parallel reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} foo(); diff --git a/clang/test/OpenMP/parallel_sections_lastprivate_messages.cpp b/clang/test/OpenMP/parallel_sections_lastprivate_messages.cpp index c71c115bd187..6d790e466937 100644 --- a/clang/test/OpenMP/parallel_sections_lastprivate_messages.cpp +++ b/clang/test/OpenMP/parallel_sections_lastprivate_messages.cpp @@ -15,7 +15,7 @@ class S2 { public: S2() : a(0) {} S2(S2 &s2) : a(s2.a) {} - static float S2s; // expected-note {{static data member is predetermined as shared}} + static float S2s; static const float S2sc; }; const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}} @@ -211,7 +211,7 @@ int main(int argc, char **argv) { { foo(); } -#pragma omp parallel sections lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}} +#pragma omp parallel sections lastprivate(S2::S2s) { foo(); } diff --git a/clang/test/OpenMP/parallel_sections_reduction_messages.cpp b/clang/test/OpenMP/parallel_sections_reduction_messages.cpp index 8b02f2315c9d..68f494f0fd26 100644 --- a/clang/test/OpenMP/parallel_sections_reduction_messages.cpp +++ b/clang/test/OpenMP/parallel_sections_reduction_messages.cpp @@ -16,7 +16,7 @@ class S2 { public: S2() : a(0) {} S2(S2 &s2) : a(s2.a) {} - static float S2s; // expected-note 2 {{static data member is predetermined as shared}} + static float S2s; static const float S2sc; }; const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}} @@ -155,7 +155,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} { foo(); } -#pragma omp parallel sections reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} +#pragma omp parallel sections reduction(&& : S2::S2s) { foo(); } @@ -300,7 +300,7 @@ int main(int argc, char **argv) { { foo(); } -#pragma omp parallel sections reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} +#pragma omp parallel sections reduction(&& : S2::S2s) { foo(); } diff --git a/clang/test/OpenMP/task_private_messages.cpp b/clang/test/OpenMP/task_private_messages.cpp index 9a3bb757681c..0352694d579e 100644 --- a/clang/test/OpenMP/task_private_messages.cpp +++ b/clang/test/OpenMP/task_private_messages.cpp @@ -14,7 +14,7 @@ class S2 { public: S2() : a(0) {} - static float S2s; // expected-note {{static data member is predetermined as shared}} + static float S2s; }; const S2 b; const S2 ba[5]; @@ -65,7 +65,7 @@ int main(int argc, char **argv) { #pragma omp task private(ba) #pragma omp task private(ca) // expected-error {{shared variable cannot be private}} #pragma omp task private(da) // expected-error {{shared variable cannot be private}} -#pragma omp task private(S2::S2s) // expected-error {{shared variable cannot be private}} +#pragma omp task private(S2::S2s) #pragma omp task private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} #pragma omp task private(threadvar) // expected-error {{threadprivate or thread local variable cannot be private}} #pragma omp task shared(i), private(i) // expected-error {{shared variable cannot be private}} expected-note {{defined as shared}} diff --git a/clang/test/OpenMP/teams_private_messages.cpp b/clang/test/OpenMP/teams_private_messages.cpp index 16ecb74ea0cb..65caaed381b6 100644 --- a/clang/test/OpenMP/teams_private_messages.cpp +++ b/clang/test/OpenMP/teams_private_messages.cpp @@ -13,7 +13,7 @@ class S2 { mutable int a; public: S2():a(0) { } - static float S2s; // expected-note {{static data member is predetermined as shared}} + static float S2s; }; const S2 b; const S2 ba[5]; @@ -88,7 +88,7 @@ int main(int argc, char **argv) { #pragma omp teams private(da) // expected-error {{shared variable cannot be private}} foo(); #pragma omp target - #pragma omp teams private(S2::S2s) // expected-error {{shared variable cannot be private}} + #pragma omp teams private(S2::S2s) foo(); #pragma omp target #pragma omp teams private(e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{calling a private constructor of class 'S5'}} diff --git a/clang/test/OpenMP/teams_reduction_messages.cpp b/clang/test/OpenMP/teams_reduction_messages.cpp index afedfc3e46fd..18b7cd4bc384 100644 --- a/clang/test/OpenMP/teams_reduction_messages.cpp +++ b/clang/test/OpenMP/teams_reduction_messages.cpp @@ -16,7 +16,7 @@ class S2 { public: S2() : a(0) {} S2(S2 &s2) : a(s2.a) {} - static float S2s; // expected-note 2 {{static data member is predetermined as shared}} + static float S2s; static const float S2sc; }; const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}} @@ -136,7 +136,7 @@ T tmain(T argc) { // expected-note 2 {{'argc' defined here}} #pragma omp teams reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}} foo(); #pragma omp target -#pragma omp teams reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} +#pragma omp teams reduction(&& : S2::S2s) foo(); #pragma omp target #pragma omp teams reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} @@ -256,7 +256,7 @@ int main(int argc, char **argv) { #pragma omp teams reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}} foo(); #pragma omp target -#pragma omp teams reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} +#pragma omp teams reduction(&& : S2::S2s) foo(); #pragma omp target #pragma omp teams reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}