@@ -146,6 +146,31 @@ class SemaOpenACCClauseVisitor {
146146 ASTContext &Ctx;
147147 ArrayRef<const OpenACCClause *> ExistingClauses;
148148
149+ // OpenACC 3.3 2.9:
150+ // A 'gang', 'worker', or 'vector' clause may not appear if a 'seq' clause
151+ // appears.
152+ bool
153+ DiagGangWorkerVectorSeqConflict (SemaOpenACC::OpenACCParsedClause &Clause) {
154+ if (Clause.getDirectiveKind () != OpenACCDirectiveKind::Loop &&
155+ !isOpenACCCombinedDirectiveKind (Clause.getDirectiveKind ()))
156+ return false ;
157+ assert (Clause.getClauseKind () == OpenACCClauseKind::Gang ||
158+ Clause.getClauseKind () == OpenACCClauseKind::Worker ||
159+ Clause.getClauseKind () == OpenACCClauseKind::Vector);
160+ const auto *Itr =
161+ llvm::find_if (ExistingClauses, llvm::IsaPred<OpenACCSeqClause>);
162+
163+ if (Itr != ExistingClauses.end ()) {
164+ SemaRef.Diag (Clause.getBeginLoc (), diag::err_acc_clause_cannot_combine)
165+ << Clause.getClauseKind () << (*Itr)->getClauseKind ()
166+ << Clause.getDirectiveKind ();
167+ SemaRef.Diag ((*Itr)->getBeginLoc (), diag::note_acc_previous_clause_here);
168+
169+ return true ;
170+ }
171+ return false ;
172+ }
173+
149174 OpenACCModifierKind
150175 CheckModifierList (SemaOpenACC::OpenACCParsedClause &Clause,
151176 OpenACCModifierKind Mods) {
@@ -1093,6 +1118,9 @@ ExprResult CheckGangRoutineExpr(SemaOpenACC &S, OpenACCDirectiveKind DK,
10931118
10941119OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorClause (
10951120 SemaOpenACC::OpenACCParsedClause &Clause) {
1121+ if (DiagGangWorkerVectorSeqConflict (Clause))
1122+ return nullptr ;
1123+
10961124 Expr *IntExpr =
10971125 Clause.getNumIntExprs () != 0 ? Clause.getIntExprs ()[0 ] : nullptr ;
10981126 if (IntExpr) {
@@ -1189,6 +1217,9 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorClause(
11891217
11901218OpenACCClause *SemaOpenACCClauseVisitor::VisitWorkerClause (
11911219 SemaOpenACC::OpenACCParsedClause &Clause) {
1220+ if (DiagGangWorkerVectorSeqConflict (Clause))
1221+ return nullptr ;
1222+
11921223 Expr *IntExpr =
11931224 Clause.getNumIntExprs () != 0 ? Clause.getIntExprs ()[0 ] : nullptr ;
11941225
@@ -1295,6 +1326,10 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitWorkerClause(
12951326
12961327OpenACCClause *SemaOpenACCClauseVisitor::VisitGangClause (
12971328 SemaOpenACC::OpenACCParsedClause &Clause) {
1329+
1330+ if (DiagGangWorkerVectorSeqConflict (Clause))
1331+ return nullptr ;
1332+
12981333 // OpenACC 3.3 Section 2.9.11: A reduction clause may not appear on a loop
12991334 // directive that has a gang clause and is within a compute construct that has
13001335 // a num_gangs clause with more than one explicit argument.
@@ -1431,6 +1466,22 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitIfPresentClause(
14311466
14321467OpenACCClause *SemaOpenACCClauseVisitor::VisitSeqClause (
14331468 SemaOpenACC::OpenACCParsedClause &Clause) {
1469+ // OpenACC 3.3 2.9:
1470+ // A 'gang', 'worker', or 'vector' clause may not appear if a 'seq' clause
1471+ // appears.
1472+ if (Clause.getDirectiveKind () == OpenACCDirectiveKind::Loop ||
1473+ isOpenACCCombinedDirectiveKind (Clause.getDirectiveKind ())) {
1474+ const auto *Itr = llvm::find_if (
1475+ ExistingClauses, llvm::IsaPred<OpenACCGangClause, OpenACCVectorClause,
1476+ OpenACCWorkerClause>);
1477+ if (Itr != ExistingClauses.end ()) {
1478+ SemaRef.Diag (Clause.getBeginLoc (), diag::err_acc_clause_cannot_combine)
1479+ << Clause.getClauseKind () << (*Itr)->getClauseKind ()
1480+ << Clause.getDirectiveKind ();
1481+ SemaRef.Diag ((*Itr)->getBeginLoc (), diag::note_acc_previous_clause_here);
1482+ return nullptr ;
1483+ }
1484+ }
14341485
14351486 return OpenACCSeqClause::Create (Ctx, Clause.getBeginLoc (),
14361487 Clause.getEndLoc ());
0 commit comments