@@ -804,6 +804,25 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorLengthClause(
804804 if (checkAlreadyHasClauseOfKind (SemaRef, ExistingClauses, Clause))
805805 return nullptr ;
806806
807+ // OpenACC 3.3 Section 2.9.4:
808+ // An argument is allowed only when the 'vector_length' does not appear on the
809+ // 'kernels' construct.
810+ if (Clause.getDirectiveKind () == OpenACCDirectiveKind::KernelsLoop) {
811+ auto VectorClauses = llvm::make_filter_range (
812+ ExistingClauses, llvm::IsaPred<OpenACCVectorClause>);
813+
814+ for (auto *VC : VectorClauses) {
815+ if (cast<OpenACCVectorClause>(VC)->hasIntExpr ()) {
816+ SemaRef.Diag (Clause.getBeginLoc (),
817+ diag::err_acc_num_arg_conflict_reverse)
818+ << OpenACCClauseKind::VectorLength << OpenACCClauseKind::Vector
819+ << /* num argument*/ 0 ;
820+ SemaRef.Diag (VC->getBeginLoc (), diag::note_acc_previous_clause_here);
821+ return nullptr ;
822+ }
823+ }
824+ }
825+
807826 assert (Clause.getIntExprs ().size () == 1 &&
808827 " Invalid number of expressions for NumWorkers" );
809828 return OpenACCVectorLengthClause::Create (
@@ -1097,6 +1116,14 @@ ExprResult DiagIntArgInvalid(SemaOpenACC &S, Expr *E, OpenACCGangKind GK,
10971116 << HasAssocKind (DK, AssocKind) << AssocKind;
10981117 return ExprError ();
10991118}
1119+ ExprResult DiagIntArgInvalid (SemaOpenACC &S, Expr *E, StringRef TagKind,
1120+ OpenACCClauseKind CK, OpenACCDirectiveKind DK,
1121+ OpenACCDirectiveKind AssocKind) {
1122+ S.Diag (E->getBeginLoc (), diag::err_acc_int_arg_invalid)
1123+ << TagKind << CK << IsOrphanLoop (DK, AssocKind) << DK
1124+ << HasAssocKind (DK, AssocKind) << AssocKind;
1125+ return ExprError ();
1126+ }
11001127
11011128ExprResult CheckGangParallelExpr (SemaOpenACC &S, OpenACCDirectiveKind DK,
11021129 OpenACCDirectiveKind AssocKind,
@@ -1172,8 +1199,9 @@ ExprResult CheckGangKernelsExpr(SemaOpenACC &S,
11721199
11731200 if (Itr != Collection.end ()) {
11741201 S.Diag (E->getBeginLoc (), diag::err_acc_num_arg_conflict)
1175- << OpenACCClauseKind::Gang << DK << HasAssocKind (DK, AssocKind)
1176- << AssocKind << OpenACCClauseKind::NumGangs;
1202+ << " num" << OpenACCClauseKind::Gang << DK
1203+ << HasAssocKind (DK, AssocKind) << AssocKind
1204+ << OpenACCClauseKind::NumGangs;
11771205
11781206 S.Diag ((*Itr)->getBeginLoc (), diag::note_acc_previous_clause_here);
11791207 return ExprError ();
@@ -1206,63 +1234,94 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorClause(
12061234 SemaOpenACC::OpenACCParsedClause &Clause) {
12071235 if (DiagIfSeqClause (Clause))
12081236 return nullptr ;
1209- // Restrictions only properly implemented on 'loop' constructs, and it is
1210- // the only construct that can do anything with this, so skip/treat as
1211- // unimplemented for the combined constructs.
1212- if (Clause.getDirectiveKind () != OpenACCDirectiveKind::Loop)
1237+
1238+ // Restrictions only properly implemented on 'loop'/'combined' constructs, and
1239+ // it is the only construct that can do anything with this, so skip/treat as
1240+ // unimplemented for the routine constructs.
1241+ if (Clause.getDirectiveKind () != OpenACCDirectiveKind::Loop &&
1242+ !isOpenACCCombinedDirectiveKind (Clause.getDirectiveKind ()))
12131243 return isNotImplemented ();
12141244
12151245 Expr *IntExpr =
12161246 Clause.getNumIntExprs () != 0 ? Clause.getIntExprs ()[0 ] : nullptr ;
12171247 if (IntExpr) {
1218- switch (SemaRef.getActiveComputeConstructInfo ().Kind ) {
1219- case OpenACCDirectiveKind::Invalid:
1220- case OpenACCDirectiveKind::Parallel:
1221- // No restriction on when 'parallel' can contain an argument.
1222- break ;
1223- case OpenACCDirectiveKind::Serial:
1224- // GCC disallows this, and there is no real good reason for us to permit
1225- // it, so disallow until we come up with a use case that makes sense.
1226- DiagIntArgInvalid (SemaRef, IntExpr, OpenACCGangKind::Num,
1227- OpenACCClauseKind::Vector, Clause.getDirectiveKind (),
1228- SemaRef.getActiveComputeConstructInfo ().Kind );
1229- IntExpr = nullptr ;
1230- break ;
1231- case OpenACCDirectiveKind::Kernels: {
1232- const auto *Itr =
1233- llvm::find_if (SemaRef.getActiveComputeConstructInfo ().Clauses ,
1234- llvm::IsaPred<OpenACCVectorLengthClause>);
1235- if (Itr != SemaRef.getActiveComputeConstructInfo ().Clauses .end ()) {
1236- SemaRef.Diag (IntExpr->getBeginLoc (), diag::err_acc_num_arg_conflict)
1237- << OpenACCClauseKind::Vector << Clause.getDirectiveKind ()
1238- << HasAssocKind (Clause.getDirectiveKind (),
1239- SemaRef.getActiveComputeConstructInfo ().Kind )
1240- << SemaRef.getActiveComputeConstructInfo ().Kind
1241- << OpenACCClauseKind::VectorLength;
1242- SemaRef.Diag ((*Itr)->getBeginLoc (),
1243- diag::note_acc_previous_clause_here);
1248+ if (!isOpenACCCombinedDirectiveKind (Clause.getDirectiveKind ())) {
1249+ switch (SemaRef.getActiveComputeConstructInfo ().Kind ) {
1250+ case OpenACCDirectiveKind::Invalid:
1251+ case OpenACCDirectiveKind::Parallel:
1252+ // No restriction on when 'parallel' can contain an argument.
1253+ break ;
1254+ case OpenACCDirectiveKind::Serial:
1255+ // GCC disallows this, and there is no real good reason for us to permit
1256+ // it, so disallow until we come up with a use case that makes sense.
1257+ DiagIntArgInvalid (SemaRef, IntExpr, " length" , OpenACCClauseKind::Vector,
1258+ Clause.getDirectiveKind (),
1259+ SemaRef.getActiveComputeConstructInfo ().Kind );
1260+ IntExpr = nullptr ;
1261+ break ;
1262+ case OpenACCDirectiveKind::Kernels: {
1263+ const auto *Itr =
1264+ llvm::find_if (SemaRef.getActiveComputeConstructInfo ().Clauses ,
1265+ llvm::IsaPred<OpenACCVectorLengthClause>);
1266+ if (Itr != SemaRef.getActiveComputeConstructInfo ().Clauses .end ()) {
1267+ SemaRef.Diag (IntExpr->getBeginLoc (), diag::err_acc_num_arg_conflict)
1268+ << " length" << OpenACCClauseKind::Vector
1269+ << Clause.getDirectiveKind ()
1270+ << HasAssocKind (Clause.getDirectiveKind (),
1271+ SemaRef.getActiveComputeConstructInfo ().Kind )
1272+ << SemaRef.getActiveComputeConstructInfo ().Kind
1273+ << OpenACCClauseKind::VectorLength;
1274+ SemaRef.Diag ((*Itr)->getBeginLoc (),
1275+ diag::note_acc_previous_clause_here);
12441276
1277+ IntExpr = nullptr ;
1278+ }
1279+ break ;
1280+ }
1281+ default :
1282+ llvm_unreachable (" Non compute construct in active compute construct" );
1283+ }
1284+ } else {
1285+ if (Clause.getDirectiveKind () == OpenACCDirectiveKind::SerialLoop) {
1286+ DiagIntArgInvalid (SemaRef, IntExpr, " length" , OpenACCClauseKind::Vector,
1287+ Clause.getDirectiveKind (),
1288+ SemaRef.getActiveComputeConstructInfo ().Kind );
12451289 IntExpr = nullptr ;
1290+ } else if (Clause.getDirectiveKind () ==
1291+ OpenACCDirectiveKind::KernelsLoop) {
1292+ const auto *Itr = llvm::find_if (
1293+ ExistingClauses, llvm::IsaPred<OpenACCVectorLengthClause>);
1294+ if (Itr != ExistingClauses.end ()) {
1295+ SemaRef.Diag (IntExpr->getBeginLoc (), diag::err_acc_num_arg_conflict)
1296+ << " length" << OpenACCClauseKind::Vector
1297+ << Clause.getDirectiveKind ()
1298+ << HasAssocKind (Clause.getDirectiveKind (),
1299+ SemaRef.getActiveComputeConstructInfo ().Kind )
1300+ << SemaRef.getActiveComputeConstructInfo ().Kind
1301+ << OpenACCClauseKind::VectorLength;
1302+ SemaRef.Diag ((*Itr)->getBeginLoc (),
1303+ diag::note_acc_previous_clause_here);
1304+
1305+ IntExpr = nullptr ;
1306+ }
12461307 }
1247- break ;
1248- }
1249- default :
1250- llvm_unreachable (" Non compute construct in active compute construct" );
12511308 }
12521309 }
12531310
1254- // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not
1255- // contain a loop with a gang, worker, or vector clause unless within a nested
1256- // compute region.
1257- if (SemaRef.LoopVectorClauseLoc .isValid ()) {
1258- // This handles the 'inner loop' diagnostic, but we cannot set that we're on
1259- // one of these until we get to the end of the construct.
1260- SemaRef.Diag (Clause.getBeginLoc (), diag::err_acc_clause_in_clause_region)
1261- << OpenACCClauseKind::Vector << OpenACCClauseKind::Vector
1262- << /* skip kernels construct info*/ 0 ;
1263- SemaRef.Diag (SemaRef.LoopVectorClauseLoc ,
1264- diag::note_acc_previous_clause_here);
1265- return nullptr ;
1311+ if (!isOpenACCCombinedDirectiveKind (Clause.getDirectiveKind ())) {
1312+ // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not
1313+ // contain a loop with a gang, worker, or vector clause unless within a
1314+ // nested compute region.
1315+ if (SemaRef.LoopVectorClauseLoc .isValid ()) {
1316+ // This handles the 'inner loop' diagnostic, but we cannot set that we're
1317+ // on one of these until we get to the end of the construct.
1318+ SemaRef.Diag (Clause.getBeginLoc (), diag::err_acc_clause_in_clause_region)
1319+ << OpenACCClauseKind::Vector << OpenACCClauseKind::Vector
1320+ << /* skip kernels construct info*/ 0 ;
1321+ SemaRef.Diag (SemaRef.LoopVectorClauseLoc ,
1322+ diag::note_acc_previous_clause_here);
1323+ return nullptr ;
1324+ }
12661325 }
12671326
12681327 return OpenACCVectorClause::Create (Ctx, Clause.getBeginLoc (),
@@ -1305,7 +1364,7 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitWorkerClause(
13051364 llvm::IsaPred<OpenACCNumWorkersClause>);
13061365 if (Itr != SemaRef.getActiveComputeConstructInfo ().Clauses .end ()) {
13071366 SemaRef.Diag (IntExpr->getBeginLoc (), diag::err_acc_num_arg_conflict)
1308- << OpenACCClauseKind::Worker << Clause.getDirectiveKind ()
1367+ << " num " << OpenACCClauseKind::Worker << Clause.getDirectiveKind ()
13091368 << HasAssocKind (Clause.getDirectiveKind (),
13101369 SemaRef.getActiveComputeConstructInfo ().Kind )
13111370 << SemaRef.getActiveComputeConstructInfo ().Kind
@@ -1334,7 +1393,7 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitWorkerClause(
13341393 llvm::IsaPred<OpenACCNumWorkersClause>);
13351394 if (Itr != ExistingClauses.end ()) {
13361395 SemaRef.Diag (IntExpr->getBeginLoc (), diag::err_acc_num_arg_conflict)
1337- << OpenACCClauseKind::Worker << Clause.getDirectiveKind ()
1396+ << " num " << OpenACCClauseKind::Worker << Clause.getDirectiveKind ()
13381397 << HasAssocKind (Clause.getDirectiveKind (),
13391398 SemaRef.getActiveComputeConstructInfo ().Kind )
13401399 << SemaRef.getActiveComputeConstructInfo ().Kind
0 commit comments