@@ -419,38 +419,77 @@ class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
419
419
: Stack(S), SemaRef(SemaRef), ErrorFound(false ), CS(CS) {}
420
420
};
421
421
422
+ // OSSClauseDSAChecker gathers for each expression in a depend clause
423
+ // all implicit data-sharings.
424
+ //
425
+ // To do so, we classify as firstprivate the base symbol if it's a pointer and is
426
+ // dereferenced by a SubscriptExpr, MemberExpr or UnaryOperator.
427
+ // Otherwise it's shared.
428
+ //
429
+ // At the same time, all symbols found inside a SubscriptExpr will be firstprivate.
430
+ // NOTE: implicit DSA from other tasks are ignored
422
431
class OSSClauseDSAChecker final : public StmtVisitor<OSSClauseDSAChecker, void > {
423
432
DSAStackTy *Stack;
424
433
Sema &SemaRef;
425
434
bool ErrorFound = false ;
426
435
llvm::SmallVector<Expr *, 4 > ImplicitFirstprivate;
427
436
llvm::SmallVector<Expr *, 4 > ImplicitShared;
428
- bool IsArraySubscriptIdx = false ;
437
+ // This is used to know we're inside a subscript expression
438
+ size_t ArraySubscriptCnt = 0 ;
439
+ // This is used to mark the innermost base symbol expression as:
440
+ // *p, p[2], p[1:2], [2]p, s.x, s->x
441
+ bool IsDerefMemberArrayBase = false ;
429
442
public:
430
443
431
444
void VisitOSSArrayShapingExpr (OSSArrayShapingExpr *E) {
445
+ if (isa<DeclRefExpr>(E->getBase ()->IgnoreParenImpCasts ()))
446
+ IsDerefMemberArrayBase = true ;
432
447
Visit (E->getBase ());
433
- IsArraySubscriptIdx = true ;
448
+ IsDerefMemberArrayBase = false ;
449
+
450
+ ArraySubscriptCnt++;
434
451
for (Stmt *S : E->getShapes ())
435
452
Visit (S);
436
- IsArraySubscriptIdx = false ;
453
+ ArraySubscriptCnt-- ;
437
454
}
438
455
439
456
void VisitOSSArraySectionExpr (OSSArraySectionExpr *E) {
457
+ if (isa<DeclRefExpr>(E->getBase ()->IgnoreParenImpCasts ()))
458
+ IsDerefMemberArrayBase = true ;
440
459
Visit (E->getBase ());
441
- IsArraySubscriptIdx = true ;
460
+ IsDerefMemberArrayBase = false ;
461
+
462
+ ArraySubscriptCnt++;
442
463
if (E->getLowerBound ())
443
464
Visit (E->getLowerBound ());
444
465
if (E->getLengthUpper ())
445
466
Visit (E->getLengthUpper ());
446
- IsArraySubscriptIdx = false ;
467
+ ArraySubscriptCnt-- ;
447
468
}
448
469
449
470
void VisitArraySubscriptExpr (ArraySubscriptExpr *E) {
471
+ if (isa<DeclRefExpr>(E->getBase ()->IgnoreParenImpCasts ()))
472
+ IsDerefMemberArrayBase = true ;
450
473
Visit (E->getBase ());
451
- IsArraySubscriptIdx = true ;
474
+ IsDerefMemberArrayBase = false ;
475
+
476
+ ArraySubscriptCnt++;
452
477
Visit (E->getIdx ());
453
- IsArraySubscriptIdx = false ;
478
+ ArraySubscriptCnt--;
479
+ }
480
+
481
+ void VisitUnaryOperator (UnaryOperator *E) {
482
+ if (isa<DeclRefExpr>(E->getSubExpr ()->IgnoreParenImpCasts ()))
483
+ IsDerefMemberArrayBase = true ;
484
+ Visit (E->getSubExpr ());
485
+ IsDerefMemberArrayBase = false ;
486
+ }
487
+
488
+ void VisitMemberExpr (MemberExpr *E) {
489
+ if (isa<DeclRefExpr>(E->getBase ()->IgnoreParenImpCasts ()))
490
+ IsDerefMemberArrayBase = true ;
491
+ Visit (E->getBase ());
492
+ IsDerefMemberArrayBase = false ;
454
493
}
455
494
456
495
void VisitCXXThisExpr (CXXThisExpr *ThisE) {
@@ -474,9 +513,16 @@ class OSSClauseDSAChecker final : public StmtVisitor<OSSClauseDSAChecker, void>
474
513
// inout(s.x) | shared(s) | struct S s;
475
514
// inout(ps->x) | firstprivate(ps) | struct S *ps;
476
515
OmpSsClauseKind VKind = OSSC_shared;
477
- if (VD->getType ()->isPointerType ())
516
+ // FIXME?: There's an overlapping between IsDerefMemberArrayBase
517
+ // and ArraySubscriptCnt
518
+ // i.e
519
+ // a[b[7]]
520
+ // b will have ArraySubscriptCnt > 0
521
+ // and IsDerefMemberArrayBase true
522
+ // Check ArraySubscriptCnt first since is more restrictive
523
+ if (ArraySubscriptCnt)
478
524
VKind = OSSC_firstprivate;
479
- else if (IsArraySubscriptIdx )
525
+ else if (VD-> getType ()-> isPointerType () && IsDerefMemberArrayBase )
480
526
VKind = OSSC_firstprivate;
481
527
482
528
SourceLocation ELoc = E->getExprLoc ();
@@ -485,18 +531,10 @@ class OSSClauseDSAChecker final : public StmtVisitor<OSSClauseDSAChecker, void>
485
531
DSAStackTy::DSAVarData DVarCurrent = Stack->getCurrentDSA (VD);
486
532
switch (DVarCurrent.CKind ) {
487
533
case OSSC_shared:
488
- if (IsArraySubscriptIdx) {
489
- // shared(n) in(array[n])
490
- break ;
491
- }
492
- if (VKind == OSSC_private || VKind == OSSC_firstprivate) {
493
- ErrorFound = true ;
494
- SemaRef.Diag (ELoc, diag::err_oss_mismatch_depend_dsa)
495
- << getOmpSsClauseName (DVarCurrent.CKind )
496
- << getOmpSsClauseName (VKind) << ERange;
497
- }
534
+ // Do nothing
498
535
break ;
499
536
case OSSC_private:
537
+ break ;
500
538
case OSSC_firstprivate:
501
539
if (VKind == OSSC_shared) {
502
540
if (DVarCurrent.Implicit ) {
0 commit comments