Revert "[OPENMP]Fix PR41767: diagnose DSA for variables in clauses with default(none)."
This implementation isn't sound as per the standard. It erroneously diagnoses e.g. the following case: ``` $ cat test.cpp void f(int n) { #pragma omp parallel default(none) if(n) ; } ``` ``` $ ./bin/clang -fopenmp test.cpp test.cpp:2:40: error: variable 'n' must have explicitly specified data sharing attributes #pragma omp parallel default(none) if(n) ^ test.cpp:2:31: note: explicit data sharing attribute requested here #pragma omp parallel default(none) if(n) ^ 1 error generated. ``` As per OpenMP Application Programming Interface Version 5.0 November 2018: * 2.19.4.1default Clause The default clause explicitly determines the data-sharing attributes of variables that are referenced *in a parallel, teams, or task generating construct and would otherwise be implicitly determined (see Section 2.19.1.1 on page 270). * 2.6.1 Determining the Number of Threads for a parallel Region Using a variable in an if or num_threads clause expression of a parallel construct causes an implicit reference to the variable in all enclosing constructs. The if clause expression and the num_threads clause expression are evaluated in the context outside of the parallel construct, This reverts commit r360073. llvm-svn: 360326
This commit is contained in:
parent
eba9a6e08f
commit
b32a02b5bc
|
@ -750,8 +750,7 @@ 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
|
||||
|
@ -2561,17 +2560,9 @@ public:
|
|||
E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
|
||||
return;
|
||||
if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
|
||||
// Check the datasharing rules for the expressions in the clauses.
|
||||
if (!CS) {
|
||||
if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
|
||||
if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
|
||||
Visit(CED->getInit());
|
||||
return;
|
||||
}
|
||||
}
|
||||
VD = VD->getCanonicalDecl();
|
||||
// Skip internally declared variables.
|
||||
if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD))
|
||||
if (VD->hasLocalStorage() && !CS->capturesVariable(VD))
|
||||
return;
|
||||
|
||||
DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
|
||||
|
@ -2582,7 +2573,7 @@ public:
|
|||
// Skip internally declared static variables.
|
||||
llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
|
||||
OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
|
||||
if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
|
||||
if (VD->hasGlobalStorage() && !CS->capturesVariable(VD) &&
|
||||
(!Res || *Res != OMPDeclareTargetDeclAttr::MT_Link))
|
||||
return;
|
||||
|
||||
|
@ -4195,90 +4186,6 @@ 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<OMPIfClause>(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();
|
||||
|
|
|
@ -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) shared(argc)
|
||||
// CHECK: #pragma omp distribute parallel for schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a) shared(argc)
|
||||
#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)
|
||||
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) shared(argc)
|
||||
// CHECK: #pragma omp distribute parallel for schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a) shared(argc)
|
||||
#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)
|
||||
for (int i = 0; i < 2; ++i)
|
||||
a = 2;
|
||||
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
|
||||
|
|
|
@ -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) shared(argc)
|
||||
// CHECK: #pragma omp distribute parallel for simd schedule(guided, argc) default(none) copyin(g) dist_schedule(static, a) private(a) shared(argc)
|
||||
#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)
|
||||
for (int i = 0; i < 2; ++i)
|
||||
a = 2;
|
||||
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
|
||||
|
|
|
@ -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) shared(argc)
|
||||
// CHECK: #pragma omp parallel for schedule(guided, argc) default(none) copyin(g) linear(a) shared(argc)
|
||||
#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)
|
||||
for (int i = 0; i < 2; ++i)
|
||||
a = 2;
|
||||
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
|
||||
|
|
|
@ -50,8 +50,6 @@ 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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) shared(argc)
|
||||
// CHECK: #pragma omp target parallel for schedule(guided, argc) default(none) linear(a) shared(argc)
|
||||
#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)
|
||||
for (int i = 0; i < 2; ++i)
|
||||
a = 2;
|
||||
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
|
||||
|
|
|
@ -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) shared(argc)
|
||||
// CHECK: #pragma omp target parallel for simd schedule(guided, argc) default(none) linear(a) shared(argc)
|
||||
#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)
|
||||
for (int i = 0; i < 2; ++i)
|
||||
a = 2;
|
||||
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
|
||||
|
|
|
@ -106,8 +106,6 @@ 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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue