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 @@ -424,6 +424,11 @@ /// for-loops (from outer to inner). const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; /// Check if the specified variable is a loop control variable for + /// given region. + /// \return The index of the loop control variable in the list of associated + /// for-loops (from outer to inner). + const LCDeclInfo isLoopControlVariable(const ValueDecl *D, const SharingMapTy &Region) const; + /// Check if the specified variable is a loop control variable for /// parent region. /// \return The index of the loop control variable in the list of associated /// for-loops (from outer to inner). @@ -946,11 +951,24 @@ case DSA_none: return DVar; case DSA_unspecified: + DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; + // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced + // in a Construct, implicitly determined] + // The loop iteration variable(s) in the associated for-loop(s) of a for or + // parallel for construct is (are) private. + // OpenMP 5.0 includes taskloop and distribute directives + if (!isOpenMPSimdDirective(DVar.DKind) && + isOpenMPLoopDirective(DVar.DKind) && + isLoopControlVariable(D, *Iter).first) { + DVar.CKind = OMPC_private; + // TODO: OpenMP 5.0: if (Dvar.DKind == OMPD_loop) DVar.CKind = OMPC_lastprivate; + return DVar; + } + // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced // in a Construct, implicitly determined, p.2] // In a parallel construct, if no default clause is present, these // variables are shared. - DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; if (isOpenMPParallelDirective(DVar.DKind) || isOpenMPTeamsDirective(DVar.DKind)) { DVar.CKind = OMPC_shared; @@ -1018,8 +1036,13 @@ const DSAStackTy::LCDeclInfo DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); + return isLoopControlVariable(D, getTopOfStack()); +} + +const DSAStackTy::LCDeclInfo +DSAStackTy::isLoopControlVariable(const ValueDecl *D, const SharingMapTy &Region) const { D = getCanonicalDecl(D); - const SharingMapTy &StackElem = getTopOfStack(); + const SharingMapTy &StackElem = Region; auto It = StackElem.LCVMap.find(D); if (It != StackElem.LCVMap.end()) return It->second;