@@ -47,6 +47,7 @@ class DSAStackTy {
4747 OmpSsClauseKind CKind = OSSC_unknown;
4848 const Expr *RefExpr = nullptr ;
4949 bool Ignore = false ;
50+ bool Implicit = false ;
5051 DSAVarData () = default ;
5152 DSAVarData (OmpSsDirectiveKind DKind, OmpSsClauseKind CKind,
5253 const Expr *RefExpr, bool Ignore)
@@ -59,6 +60,7 @@ class DSAStackTy {
5960 OmpSsClauseKind Attributes = OSSC_unknown;
6061 const Expr * RefExpr;
6162 bool Ignore = false ;
63+ bool Implicit = false ;
6264 };
6365 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8 >;
6466
@@ -106,7 +108,8 @@ class DSAStackTy {
106108 }
107109
108110 // / Adds explicit data sharing attribute to the specified declaration.
109- void addDSA (const ValueDecl *D, const Expr *E, OmpSsClauseKind A, bool Ignore=false );
111+ void addDSA (const ValueDecl *D, const Expr *E, OmpSsClauseKind A,
112+ bool Ignore, bool Implicit);
110113
111114 // / Returns data sharing attributes from top of the stack for the
112115 // / specified declaration.
@@ -180,20 +183,23 @@ DSAStackTy::DSAVarData DSAStackTy::getDSA(iterator &Iter,
180183 const DSAInfo &Data = Iter->SharingMap .lookup (D);
181184 DVar.RefExpr = Data.RefExpr ;
182185 DVar.Ignore = Data.Ignore ;
186+ DVar.Implicit = Data.Implicit ;
183187 DVar.CKind = Data.Attributes ;
184188 return DVar;
185189 }
186190
187191 return DVar;
188192}
189193
190- void DSAStackTy::addDSA (const ValueDecl *D, const Expr *E, OmpSsClauseKind A, bool Ignore) {
194+ void DSAStackTy::addDSA (const ValueDecl *D, const Expr *E, OmpSsClauseKind A,
195+ bool Ignore, bool Implicit) {
191196 D = getCanonicalDecl (D);
192197 assert (!isStackEmpty () && " Data-sharing attributes stack is empty" );
193198 DSAInfo &Data = Stack.back ().SharingMap [D];
194199 Data.Attributes = A;
195200 Data.RefExpr = E;
196201 Data.Ignore = Ignore;
202+ Data.Implicit = Implicit;
197203}
198204
199205const DSAStackTy::DSAVarData DSAStackTy::getTopDSA (ValueDecl *D,
@@ -336,13 +342,13 @@ class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
336342 if (isOmpSsTaskingDirective (DKind))
337343 ImplicitShared.push_back (E);
338344 // Record DSA as Ignored to avoid making the same node again
339- Stack->addDSA (VD, E, OSSC_shared, /* Ignore=*/ true );
345+ Stack->addDSA (VD, E, OSSC_shared, /* Ignore=*/ true , /* Implicit= */ true );
340346 break ;
341347 case DSA_none:
342348 if (!DVarCurrent.Ignore ) {
343349 SemaRef.Diag (E->getExprLoc (), diag::err_oss_not_defined_dsa_when_default_none) << E->getDecl ();
344350 // Record DSA as ignored to diagnostic only once
345- Stack->addDSA (VD, E, OSSC_unknown, /* Ignore=*/ true );
351+ Stack->addDSA (VD, E, OSSC_unknown, /* Ignore=*/ true , /* Implicit= */ true );
346352 }
347353 break ;
348354 case DSA_unspecified:
@@ -356,7 +362,7 @@ class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
356362 ImplicitFirstprivate.push_back (E);
357363
358364 // Record DSA as Ignored to avoid making the same node again
359- Stack->addDSA (VD, E, OSSC_firstprivate, /* Ignore=*/ true );
365+ Stack->addDSA (VD, E, OSSC_firstprivate, /* Ignore=*/ true , /* Implicit= */ true );
360366 } else {
361367 // If no default clause is present and the variable was shared/global
362368 // in the context encountering the construct, the variable will be shared.
@@ -366,7 +372,7 @@ class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
366372 ImplicitShared.push_back (E);
367373
368374 // Record DSA as Ignored to avoid making the same node again
369- Stack->addDSA (VD, E, OSSC_shared, /* Ignore=*/ true );
375+ Stack->addDSA (VD, E, OSSC_shared, /* Ignore=*/ true , /* Implicit= */ true );
370376 }
371377 }
372378 }
@@ -479,6 +485,10 @@ class OSSClauseDSAChecker final : public StmtVisitor<OSSClauseDSAChecker, void>
479485 DSAStackTy::DSAVarData DVarCurrent = Stack->getCurrentDSA (VD);
480486 switch (DVarCurrent.CKind ) {
481487 case OSSC_shared:
488+ if (IsArraySubscriptIdx) {
489+ // shared(n) in(array[n])
490+ break ;
491+ }
482492 if (VKind == OSSC_private || VKind == OSSC_firstprivate) {
483493 ErrorFound = true ;
484494 SemaRef.Diag (ELoc, diag::err_oss_mismatch_depend_dsa)
@@ -489,28 +499,34 @@ class OSSClauseDSAChecker final : public StmtVisitor<OSSClauseDSAChecker, void>
489499 case OSSC_private:
490500 case OSSC_firstprivate:
491501 if (VKind == OSSC_shared) {
492- ErrorFound = true ;
493- SemaRef.Diag (ELoc, diag::err_oss_mismatch_depend_dsa)
494- << getOmpSsClauseName (DVarCurrent.CKind )
495- << getOmpSsClauseName (VKind) << ERange;
502+ if (DVarCurrent.Implicit ) {
503+ // Promote Implicit firstprivate to Implicit shared
504+ auto It = ImplicitFirstprivate.begin ();
505+ while (It != ImplicitFirstprivate.end ()) {
506+ if (*It == DVarCurrent.RefExpr ) break ;
507+ ++It;
508+ }
509+ assert (It != ImplicitFirstprivate.end ());
510+ ImplicitFirstprivate.erase (It);
511+
512+ ImplicitShared.push_back (E);
513+ // Rewrite DSA
514+ Stack->addDSA (VD, E, VKind, /* Ignore=*/ false , /* Implicit=*/ true );
515+ } else {
516+ ErrorFound = true ;
517+ SemaRef.Diag (ELoc, diag::err_oss_mismatch_depend_dsa)
518+ << getOmpSsClauseName (DVarCurrent.CKind )
519+ << getOmpSsClauseName (VKind) << ERange;
520+ }
496521 }
497522 break ;
498523 case OSSC_unknown:
499- // No DSA explicit
500- if (Stack->getCurrentDefaultDataSharingAttributtes () == DSA_none) {
501- // KO: but default(none)
502- // Record DSA as ignored
503- SemaRef.Diag (ELoc, diag::err_oss_not_defined_dsa_when_default_none) << E->getDecl ();
504- Stack->addDSA (VD, E, OSSC_unknown, /* Ignore=*/ true );
505- } else {
506- // OK: record DSA as explicit
507- if (VKind == OSSC_shared)
508- ImplicitShared.push_back (E);
509- if (VKind == OSSC_firstprivate)
510- ImplicitFirstprivate.push_back (E);
524+ if (VKind == OSSC_shared)
525+ ImplicitShared.push_back (E);
526+ if (VKind == OSSC_firstprivate)
527+ ImplicitFirstprivate.push_back (E);
511528
512- Stack->addDSA (VD, E, VKind);
513- }
529+ Stack->addDSA (VD, E, VKind, /* Ignore=*/ false , /* Implicit=*/ true );
514530
515531 break ;
516532 default :
@@ -595,46 +611,47 @@ void Sema::ActOnOmpSsAfterClauseGathering(SmallVectorImpl<OSSClause *>& Clauses)
595611
596612 bool ErrorFound = false ;
597613
614+ OSSClauseDSAChecker OSSDependChecker (DSAStack, *this );
598615 for (auto *Clause : Clauses) {
599- OSSClauseDSAChecker OSSDependChecker (DSAStack, *this );
600616 if (isa<OSSDependClause>(Clause)) {
601617 OSSDependChecker.VisitOSSDepend (cast<OSSDependClause> (Clause));
618+ }
619+ // FIXME: how to handle an error?
620+ if (OSSDependChecker.isErrorFound ())
621+ ErrorFound = true ;
622+ }
602623
603- if (OSSDependChecker.isErrorFound ())
604- ErrorFound = true ;
605624
606- SmallVector<Expr *, 4 > ImplicitShared (
607- OSSDependChecker.getImplicitShared ().begin (),
608- OSSDependChecker.getImplicitShared ().end ());
625+ SmallVector<Expr *, 4 > ImplicitShared (
626+ OSSDependChecker.getImplicitShared ().begin (),
627+ OSSDependChecker.getImplicitShared ().end ());
609628
610- SmallVector<Expr *, 4 > ImplicitFirstprivate (
611- OSSDependChecker.getImplicitFirstprivate ().begin (),
612- OSSDependChecker.getImplicitFirstprivate ().end ());
629+ SmallVector<Expr *, 4 > ImplicitFirstprivate (
630+ OSSDependChecker.getImplicitFirstprivate ().begin (),
631+ OSSDependChecker.getImplicitFirstprivate ().end ());
613632
614- if (!ImplicitShared.empty ()) {
615- if (OSSClause *Implicit = ActOnOmpSsSharedClause (
616- ImplicitShared, SourceLocation (), SourceLocation (),
617- SourceLocation (), /* isImplicit=*/ true )) {
618- Clauses.push_back (Implicit);
619- if (cast<OSSSharedClause>(Implicit)->varlist_size () != ImplicitShared.size ())
620- ErrorFound = true ;
633+ if (!ImplicitShared.empty ()) {
634+ if (OSSClause *Implicit = ActOnOmpSsSharedClause (
635+ ImplicitShared, SourceLocation (), SourceLocation (),
636+ SourceLocation (), /* isImplicit=*/ true )) {
637+ Clauses.push_back (Implicit);
638+ if (cast<OSSSharedClause>(Implicit)->varlist_size () != ImplicitShared.size ())
639+ ErrorFound = true ;
621640
622- } else {
623- ErrorFound = true ;
624- }
625- }
641+ } else {
642+ ErrorFound = true ;
643+ }
644+ }
626645
627- if (!ImplicitFirstprivate.empty ()) {
628- if (OSSClause *Implicit = ActOnOmpSsFirstprivateClause (
629- ImplicitFirstprivate, SourceLocation (), SourceLocation (),
630- SourceLocation ())) {
631- Clauses.push_back (Implicit);
632- if (cast<OSSFirstprivateClause>(Implicit)->varlist_size () != ImplicitFirstprivate.size ())
633- ErrorFound = true ;
634- } else {
635- ErrorFound = true ;
636- }
637- }
646+ if (!ImplicitFirstprivate.empty ()) {
647+ if (OSSClause *Implicit = ActOnOmpSsFirstprivateClause (
648+ ImplicitFirstprivate, SourceLocation (), SourceLocation (),
649+ SourceLocation ())) {
650+ Clauses.push_back (Implicit);
651+ if (cast<OSSFirstprivateClause>(Implicit)->varlist_size () != ImplicitFirstprivate.size ())
652+ ErrorFound = true ;
653+ } else {
654+ ErrorFound = true ;
638655 }
639656 }
640657}
@@ -1017,7 +1034,7 @@ Sema::ActOnOmpSsSharedClause(ArrayRef<Expr *> Vars,
10171034 << getOmpSsClauseName (OSSC_shared);
10181035 continue ;
10191036 }
1020- DSAStack->addDSA (D, RefExpr, OSSC_shared);
1037+ DSAStack->addDSA (D, RefExpr, OSSC_shared, /* Ignore= */ false , /* Implicit= */ false );
10211038 ClauseVars.push_back (RefExpr);
10221039 }
10231040
@@ -1055,7 +1072,7 @@ Sema::ActOnOmpSsPrivateClause(ArrayRef<Expr *> Vars,
10551072 << getOmpSsClauseName (OSSC_private);
10561073 continue ;
10571074 }
1058- DSAStack->addDSA (D, RefExpr, OSSC_private);
1075+ DSAStack->addDSA (D, RefExpr, OSSC_private, /* Ignore= */ false , /* Implicit= */ false );
10591076 ClauseVars.push_back (RefExpr);
10601077 }
10611078
@@ -1093,7 +1110,7 @@ Sema::ActOnOmpSsFirstprivateClause(ArrayRef<Expr *> Vars,
10931110 << getOmpSsClauseName (OSSC_firstprivate);
10941111 continue ;
10951112 }
1096- DSAStack->addDSA (D, RefExpr, OSSC_firstprivate);
1113+ DSAStack->addDSA (D, RefExpr, OSSC_firstprivate, /* Ignore= */ false , /* Implicit= */ false );
10971114 ClauseVars.push_back (RefExpr);
10981115 }
10991116
0 commit comments