|
@@ -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<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->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<OMPDeclareTargetDeclAttr::MapTypeTy> 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<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();
|