@@ -357,6 +357,79 @@ class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
357357 DSAAttrChecker (DSAStackTy *S, Sema &SemaRef, Stmt *CS)
358358 : Stack(S), SemaRef(SemaRef), ErrorFound(false ), CS(CS) {}
359359};
360+
361+ class OSSClauseDSAChecker final : public StmtVisitor<OSSClauseDSAChecker, void > {
362+ DSAStackTy *Stack;
363+ Sema &SemaRef;
364+ bool ErrorFound = false ;
365+ public:
366+ void VisitDeclRefExpr (DeclRefExpr *E) {
367+ if (E->isTypeDependent () || E->isValueDependent () ||
368+ E->containsUnexpandedParameterPack () || E->isInstantiationDependent ())
369+ return ;
370+
371+ if (auto *VD = dyn_cast<VarDecl>(E->getDecl ())) {
372+ VD = VD->getCanonicalDecl ();
373+ // inout(x) | shared(x) | int x;
374+ // inout(p[i]) | firstprivate(p) | int *p;
375+ // inout(a[i]) | shared(a) | int a[N];
376+ // inout(*p)/inout(p[0]) | firstprivate(p) | int *p;
377+ // inout(s.x) | shared(s) | struct S s;
378+ // inout(ps->x) | firstprivate(ps) | struct S *ps;
379+ OmpSsClauseKind VKind = OSSC_shared;
380+ if (VD->getType ()->isPointerType ())
381+ VKind = OSSC_firstprivate;
382+
383+ SourceLocation ELoc = E->getExprLoc ();
384+ SourceRange ERange = E->getSourceRange ();
385+
386+ DSAStackTy::DSAVarData DVarCurrent = Stack->getCurrentDSA (VD);
387+ switch (DVarCurrent.CKind ) {
388+ case OSSC_shared:
389+ if (VKind == OSSC_private || VKind == OSSC_firstprivate) {
390+ ErrorFound = true ;
391+ SemaRef.Diag (ELoc, diag::err_oss_mismatch_depend_dsa)
392+ << getOmpSsClauseName (DVarCurrent.CKind )
393+ << getOmpSsClauseName (VKind) << ERange;
394+ }
395+ break ;
396+ case OSSC_private:
397+ case OSSC_firstprivate:
398+ if (VKind == OSSC_shared) {
399+ ErrorFound = true ;
400+ SemaRef.Diag (ELoc, diag::err_oss_mismatch_depend_dsa)
401+ << getOmpSsClauseName (DVarCurrent.CKind )
402+ << getOmpSsClauseName (VKind) << ERange;
403+ }
404+ break ;
405+ default :
406+ // OK: no DSA explicit, record DSA as explicit, but do not
407+ // make a node for it
408+ Stack->addDSA (VD, E, VKind, false );
409+ break ;
410+ }
411+ }
412+ }
413+
414+ void VisitOSSDepend (OSSDependClause *Clause) {
415+ for (Stmt *Child : Clause->children ()) {
416+ if (Child)
417+ Visit (Child);
418+ }
419+ }
420+
421+ void VisitStmt (Stmt *S) {
422+ for (Stmt *C : S->children ()) {
423+ if (C)
424+ Visit (C);
425+ }
426+ }
427+
428+ bool isErrorFound () const { return ErrorFound; }
429+
430+ OSSClauseDSAChecker (DSAStackTy *S, Sema &SemaRef)
431+ : Stack(S), SemaRef(SemaRef), ErrorFound(false ) {}
432+ };
360433} // namespace
361434
362435void Sema::InitDataSharingAttributesStackOmpSs () {
@@ -400,10 +473,19 @@ getListOfPossibleValues(OmpSsClauseKind K, unsigned First, unsigned Last,
400473 return Out.str ();
401474}
402475
476+ void Sema::ActOnOmpSsAfterClauseGathering (ArrayRef<OSSClause *> Clauses) {
477+ OSSClauseDSAChecker OSSDependChecker (DSAStack, *this );
478+ for (auto *Clause : Clauses) {
479+ if (Clause->getClauseKind () == OSSC_depend)
480+ OSSDependChecker.VisitOSSDepend (cast<OSSDependClause> (Clause));
481+ }
482+ }
483+
403484StmtResult Sema::ActOnOmpSsExecutableDirective (ArrayRef<OSSClause *> Clauses,
404485 OmpSsDirectiveKind Kind, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
405486
406487 bool ErrorFound = false ;
488+
407489 llvm::SmallVector<OSSClause *, 8 > ClausesWithImplicit;
408490 ClausesWithImplicit.append (Clauses.begin (), Clauses.end ());
409491 if (AStmt) {
@@ -412,7 +494,7 @@ StmtResult Sema::ActOnOmpSsExecutableDirective(ArrayRef<OSSClause *> Clauses,
412494 Stmt *S = AStmt;
413495 DSAChecker.Visit (S);
414496 if (DSAChecker.isErrorFound ())
415- return StmtError () ;
497+ ErrorFound = true ;
416498
417499 SmallVector<Expr *, 4 > ImplicitShared (
418500 DSAChecker.getImplicitShared ().begin (),
0 commit comments