From 03fbaba68257f6ebdec4aceec394580bd29e0b13 Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Mon, 6 May 2019 20:07:20 +0000 Subject: [OPENMP]Fix PR41767: diagnose DSA for variables in clauses with default(none). If the combined directive has default(none) clause and has clauses for inner directive that reference some variables, for which data-sharing attributes are not specified, the error messages should be emitted for such variables. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@360073 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaOpenMP.cpp | 99 +++++++++++++++++++++- test/OpenMP/distribute_parallel_for_ast_print.cpp | 8 +- .../distribute_parallel_for_simd_ast_print.cpp | 4 +- test/OpenMP/parallel_for_ast_print.cpp | 4 +- test/OpenMP/parallel_for_schedule_messages.cpp | 2 + test/OpenMP/target_parallel_for_ast_print.cpp | 4 +- test/OpenMP/target_parallel_for_simd_ast_print.cpp | 4 +- ...t_teams_distribute_parallel_for_if_messages.cpp | 2 + 8 files changed, 112 insertions(+), 15 deletions(-) diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index 276f1506c4..c6c3a6b590 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -750,7 +750,8 @@ bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { } bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { - return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || DKind == OMPD_unknown; + return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || + DKind == OMPD_unknown; } } // namespace @@ -2560,9 +2561,17 @@ public: E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) return; if (auto *VD = dyn_cast(E->getDecl())) { + // Check the datasharing rules for the expressions in the clauses. + if (!CS) { + if (auto *CED = dyn_cast(VD)) + if (!CED->hasAttr()) { + Visit(CED->getInit()); + return; + } + } VD = VD->getCanonicalDecl(); // Skip internally declared variables. - if (VD->hasLocalStorage() && !CS->capturesVariable(VD)) + if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD)) return; DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); @@ -2573,7 +2582,7 @@ public: // Skip internally declared static variables. llvm::Optional Res = OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); - if (VD->hasGlobalStorage() && !CS->capturesVariable(VD) && + if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && (!Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) return; @@ -4186,6 +4195,90 @@ StmtResult Sema::ActOnOpenMPExecutableDirective( ErrorFound = Res.isInvalid() || ErrorFound; + // Check variables in the clauses if default(none) was specified. + if (DSAStack->getDefaultDSA() == DSA_none) { + DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); + for (OMPClause *C : Clauses) { + switch (C->getClauseKind()) { + case OMPC_num_threads: + case OMPC_dist_schedule: + // Do not analyse if no parent teams directive. + if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective())) + break; + continue; + case OMPC_if: + if ((isOpenMPTeamsDirective(DSAStack->getCurrentDirective()) && + cast(C)->getNameModifier() != OMPD_target) || + isOpenMPParallelDirective(DSAStack->getCurrentDirective())) + break; + continue; + case OMPC_schedule: + break; + case OMPC_ordered: + case OMPC_device: + case OMPC_num_teams: + case OMPC_thread_limit: + case OMPC_priority: + case OMPC_grainsize: + case OMPC_num_tasks: + case OMPC_hint: + case OMPC_collapse: + case OMPC_safelen: + case OMPC_simdlen: + case OMPC_final: + case OMPC_default: + case OMPC_proc_bind: + case OMPC_private: + case OMPC_firstprivate: + case OMPC_lastprivate: + case OMPC_shared: + case OMPC_reduction: + case OMPC_task_reduction: + case OMPC_in_reduction: + case OMPC_linear: + case OMPC_aligned: + case OMPC_copyin: + case OMPC_copyprivate: + case OMPC_nowait: + case OMPC_untied: + case OMPC_mergeable: + case OMPC_allocate: + case OMPC_read: + case OMPC_write: + case OMPC_update: + case OMPC_capture: + case OMPC_seq_cst: + case OMPC_depend: + case OMPC_threads: + case OMPC_simd: + case OMPC_map: + case OMPC_nogroup: + case OMPC_defaultmap: + case OMPC_to: + case OMPC_from: + case OMPC_use_device_ptr: + case OMPC_is_device_ptr: + continue; + case OMPC_allocator: + case OMPC_flush: + case OMPC_threadprivate: + case OMPC_uniform: + case OMPC_unknown: + case OMPC_unified_address: + case OMPC_unified_shared_memory: + case OMPC_reverse_offload: + case OMPC_dynamic_allocators: + case OMPC_atomic_default_mem_order: + llvm_unreachable("Unexpected clause"); + } + for (Stmt *CC : C->children()) { + if (CC) + DSAChecker.Visit(CC); + } + } + for (auto &P : DSAChecker.getVarsWithInheritedDSA()) + VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); + } for (const auto &P : VarsWithInheritedDSA) { Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) << P.first << P.second->getSourceRange(); diff --git a/test/OpenMP/distribute_parallel_for_ast_print.cpp b/test/OpenMP/distribute_parallel_for_ast_print.cpp index 56bae3965b..3b32d08eb3 100644 --- a/test/OpenMP/distribute_parallel_for_ast_print.cpp +++ b/test/OpenMP/distribute_parallel_for_ast_print.cpp @@ -122,8 +122,8 @@ void foo(int argc, char **argv) { [&]() { #pragma omp target #pragma omp teams -#pragma omp distribute parallel for schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a) - // CHECK: #pragma omp distribute parallel for schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a) +#pragma omp distribute parallel for schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a) shared(argc) + // CHECK: #pragma omp distribute parallel for schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a) shared(argc) for (int i = 0; i < 2; ++i) // CHECK: for (int i = 0; i < 2; ++i) [&]() { @@ -156,8 +156,8 @@ int main(int argc, char **argv) { #pragma omp threadprivate(g) #pragma omp target #pragma omp teams -#pragma omp distribute parallel for schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a) - // CHECK: #pragma omp distribute parallel for schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a) +#pragma omp distribute parallel for schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a) shared(argc) + // CHECK: #pragma omp distribute parallel for schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a) shared(argc) for (int i = 0; i < 2; ++i) a = 2; // CHECK-NEXT: for (int i = 0; i < 2; ++i) diff --git a/test/OpenMP/distribute_parallel_for_simd_ast_print.cpp b/test/OpenMP/distribute_parallel_for_simd_ast_print.cpp index db3300ed29..137a7460f5 100644 --- a/test/OpenMP/distribute_parallel_for_simd_ast_print.cpp +++ b/test/OpenMP/distribute_parallel_for_simd_ast_print.cpp @@ -123,8 +123,8 @@ int main(int argc, char **argv) { #pragma omp threadprivate(g) #pragma omp target #pragma omp teams -#pragma omp distribute parallel for simd schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a) - // CHECK: #pragma omp distribute parallel for simd schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a) +#pragma omp distribute parallel for simd schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a) shared(argc) + // CHECK: #pragma omp distribute parallel for simd schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a) shared(argc) for (int i = 0; i < 2; ++i) a = 2; // CHECK-NEXT: for (int i = 0; i < 2; ++i) diff --git a/test/OpenMP/parallel_for_ast_print.cpp b/test/OpenMP/parallel_for_ast_print.cpp index 8e02ec40c2..06b6ab3b66 100644 --- a/test/OpenMP/parallel_for_ast_print.cpp +++ b/test/OpenMP/parallel_for_ast_print.cpp @@ -132,8 +132,8 @@ int main(int argc, char **argv) { // CHECK: static int a; static float g; #pragma omp threadprivate(g) -#pragma omp parallel for schedule(guided, argc) default(none) copyin(g) linear(a) - // CHECK: #pragma omp parallel for schedule(guided, argc) default(none) copyin(g) linear(a) +#pragma omp parallel for schedule(guided, argc) default(none) copyin(g) linear(a) shared(argc) + // CHECK: #pragma omp parallel for schedule(guided, argc) default(none) copyin(g) linear(a) shared(argc) for (int i = 0; i < 2; ++i) a = 2; // CHECK-NEXT: for (int i = 0; i < 2; ++i) diff --git a/test/OpenMP/parallel_for_schedule_messages.cpp b/test/OpenMP/parallel_for_schedule_messages.cpp index 5664529956..dfdd36dddd 100644 --- a/test/OpenMP/parallel_for_schedule_messages.cpp +++ b/test/OpenMP/parallel_for_schedule_messages.cpp @@ -50,6 +50,8 @@ T tmain(T argc, S **argv) { for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; #pragma omp parallel for schedule (static, N) // expected-error {{argument to 'schedule' clause must be a strictly positive integer value}} for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; + #pragma omp parallel for schedule (static, argc+argv[0][0]) default(none) // expected-error 2 {{variable 'argv' must have explicitly specified data sharing attributes}} expected-error 2 {{variable 'argc' must have explicitly specified data sharing attributes}} expected-note 4 {{explicit data sharing attribute requested here}} + for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; return argc; } diff --git a/test/OpenMP/target_parallel_for_ast_print.cpp b/test/OpenMP/target_parallel_for_ast_print.cpp index 5e22ef3dd8..80c20baca0 100644 --- a/test/OpenMP/target_parallel_for_ast_print.cpp +++ b/test/OpenMP/target_parallel_for_ast_print.cpp @@ -176,8 +176,8 @@ int main(int argc, char **argv) { // CHECK: static int a; static float g; #pragma omp threadprivate(g) -#pragma omp target parallel for schedule(guided, argc) default(none) linear(a) - // CHECK: #pragma omp target parallel for schedule(guided, argc) default(none) linear(a) +#pragma omp target parallel for schedule(guided, argc) default(none) linear(a) shared(argc) + // CHECK: #pragma omp target parallel for schedule(guided, argc) default(none) linear(a) shared(argc) for (int i = 0; i < 2; ++i) a = 2; // CHECK-NEXT: for (int i = 0; i < 2; ++i) diff --git a/test/OpenMP/target_parallel_for_simd_ast_print.cpp b/test/OpenMP/target_parallel_for_simd_ast_print.cpp index 4ac606d90e..a368b8a088 100644 --- a/test/OpenMP/target_parallel_for_simd_ast_print.cpp +++ b/test/OpenMP/target_parallel_for_simd_ast_print.cpp @@ -200,8 +200,8 @@ int main(int argc, char **argv) { // CHECK: int clen = 5; static float g; #pragma omp threadprivate(g) -#pragma omp target parallel for simd schedule(guided, argc) default(none) linear(a) - // CHECK: #pragma omp target parallel for simd schedule(guided, argc) default(none) linear(a) +#pragma omp target parallel for simd schedule(guided, argc) default(none) linear(a) shared(argc) + // CHECK: #pragma omp target parallel for simd schedule(guided, argc) default(none) linear(a) shared(argc) for (int i = 0; i < 2; ++i) a = 2; // CHECK-NEXT: for (int i = 0; i < 2; ++i) diff --git a/test/OpenMP/target_teams_distribute_parallel_for_if_messages.cpp b/test/OpenMP/target_teams_distribute_parallel_for_if_messages.cpp index 6f990f7bd2..328e191ed3 100644 --- a/test/OpenMP/target_teams_distribute_parallel_for_if_messages.cpp +++ b/test/OpenMP/target_teams_distribute_parallel_for_if_messages.cpp @@ -106,6 +106,8 @@ int main(int argc, char **argv) { for (i = 0; i < argc; ++i) foo(); #pragma omp target teams distribute parallel for if(distribute : argc) // expected-error {{directive name modifier 'distribute' is not allowed for '#pragma omp target teams distribute parallel for'}} for (i = 0; i < argc; ++i) foo(); +#pragma omp target teams distribute parallel for default(none) if(argc+argv[0][0]) // expected-error {{variable 'argv' must have explicitly specified data sharing attributes}} expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} expected-note 2 {{explicit data sharing attribute requested here}} + for (i = 0; i < argc; ++i) foo(); return tmain(argc, argv); } -- cgit v1.2.3