@@ -14160,42 +14160,43 @@ StmtResult SemaOpenMP::ActOnOpenMPTargetTeamsDistributeSimdDirective(
14160
14160
}
14161
14161
14162
14162
// Overloaded base case function
14163
- template <typename T, typename F>
14164
- static bool tryHandleAs(T *t, F &&) {
14165
- return false;
14163
+ template <typename T, typename F> static bool tryHandleAs(T *t, F &&) {
14164
+ return false;
14166
14165
}
14167
14166
14168
14167
/**
14169
- * Tries to recursively cast `t` to one of the given types and invokes `f` if successful.
14168
+ * Tries to recursively cast `t` to one of the given types and invokes `f` if
14169
+ * successful.
14170
14170
*
14171
14171
* @tparam Class The first type to check.
14172
14172
* @tparam Rest The remaining types to check.
14173
14173
* @tparam T The base type of `t`.
14174
- * @tparam F The callable type for the function to invoke upon a successful cast.
14174
+ * @tparam F The callable type for the function to invoke upon a successful
14175
+ * cast.
14175
14176
* @param t The object to be checked.
14176
14177
* @param f The function to invoke if `t` matches `Class`.
14177
14178
* @return `true` if `t` matched any type and `f` was called, otherwise `false`.
14178
14179
*/
14179
14180
template <typename Class, typename... Rest, typename T, typename F>
14180
14181
static bool tryHandleAs(T *t, F &&f) {
14181
- if (Class *c = dyn_cast<Class>(t)) {
14182
- f(c);
14183
- return true;
14184
- } else {
14185
- return tryHandleAs<Rest...>(t, std::forward<F>(f));
14186
- }
14182
+ if (Class *c = dyn_cast<Class>(t)) {
14183
+ f(c);
14184
+ return true;
14185
+ } else {
14186
+ return tryHandleAs<Rest...>(t, std::forward<F>(f));
14187
+ }
14187
14188
}
14188
14189
14189
14190
// Updates OriginalInits by checking Transform against loop transformation
14190
14191
// directives and appending their pre-inits if a match is found.
14191
14192
static void updatePreInits(OMPLoopBasedDirective *Transform,
14192
14193
SmallVectorImpl<SmallVector<Stmt *, 0>> &PreInits) {
14193
- if (!tryHandleAs<OMPTileDirective, OMPUnrollDirective, OMPReverseDirective,
14194
- OMPInterchangeDirective, OMPFuseDirective>(
14195
- Transform, [&PreInits](auto *Dir) {
14196
- appendFlattenedStmtList(PreInits.back(), Dir->getPreInits());
14197
- }))
14198
- llvm_unreachable("Unhandled loop transformation");
14194
+ if (!tryHandleAs<OMPTileDirective, OMPUnrollDirective, OMPReverseDirective,
14195
+ OMPInterchangeDirective, OMPFuseDirective>(
14196
+ Transform, [&PreInits](auto *Dir) {
14197
+ appendFlattenedStmtList(PreInits.back(), Dir->getPreInits());
14198
+ }))
14199
+ llvm_unreachable("Unhandled loop transformation");
14199
14200
}
14200
14201
14201
14202
bool SemaOpenMP::checkTransformableLoopNest(
@@ -14273,43 +14274,42 @@ class NestedLoopCounterVisitor : public DynamicRecursiveASTVisitor {
14273
14274
unsigned getNestedLoopCount() const { return NestedLoopCount; }
14274
14275
14275
14276
bool VisitForStmt(ForStmt *FS) override {
14276
- ++NestedLoopCount;
14277
- return true;
14277
+ ++NestedLoopCount;
14278
+ return true;
14278
14279
}
14279
14280
14280
14281
bool VisitCXXForRangeStmt(CXXForRangeStmt *FRS) override {
14281
- ++NestedLoopCount;
14282
- return true;
14282
+ ++NestedLoopCount;
14283
+ return true;
14283
14284
}
14284
14285
14285
14286
bool TraverseStmt(Stmt *S) override {
14286
- if (!S)
14287
+ if (!S)
14287
14288
return true;
14288
14289
14289
- // Skip traversal of all expressions, including special cases like
14290
- // LambdaExpr, StmtExpr, BlockExpr, and RequiresExpr. These expressions
14291
- // may contain inner statements (and even loops), but they are not part
14292
- // of the syntactic body of the surrounding loop structure.
14293
- // Therefore must not be counted
14294
- if (isa<Expr>(S))
14290
+ // Skip traversal of all expressions, including special cases like
14291
+ // LambdaExpr, StmtExpr, BlockExpr, and RequiresExpr. These expressions
14292
+ // may contain inner statements (and even loops), but they are not part
14293
+ // of the syntactic body of the surrounding loop structure.
14294
+ // Therefore must not be counted
14295
+ if (isa<Expr>(S))
14295
14296
return true;
14296
14297
14297
- // Only recurse into CompoundStmt (block {}) and loop bodies
14298
- if (isa<CompoundStmt>(S) || isa<ForStmt>(S) ||
14299
- isa<CXXForRangeStmt>(S)) {
14298
+ // Only recurse into CompoundStmt (block {}) and loop bodies
14299
+ if (isa<CompoundStmt>(S) || isa<ForStmt>(S) || isa<CXXForRangeStmt>(S)) {
14300
14300
return DynamicRecursiveASTVisitor::TraverseStmt(S);
14301
- }
14301
+ }
14302
14302
14303
- // Stop traversal of the rest of statements, that break perfect
14304
- // loop nesting, such as control flow (IfStmt, SwitchStmt...)
14305
- return true;
14303
+ // Stop traversal of the rest of statements, that break perfect
14304
+ // loop nesting, such as control flow (IfStmt, SwitchStmt...)
14305
+ return true;
14306
14306
}
14307
14307
14308
14308
bool TraverseDecl(Decl *D) override {
14309
- // Stop in the case of finding a declaration, it is not important
14310
- // in order to find nested loops (Possible CXXRecordDecl, RecordDecl,
14311
- // FunctionDecl...)
14312
- return true;
14309
+ // Stop in the case of finding a declaration, it is not important
14310
+ // in order to find nested loops (Possible CXXRecordDecl, RecordDecl,
14311
+ // FunctionDecl...)
14312
+ return true;
14313
14313
}
14314
14314
};
14315
14315
@@ -14467,15 +14467,14 @@ bool SemaOpenMP::analyzeLoopSequence(
14467
14467
return isa<OMPLoopTransformationDirective>(Child);
14468
14468
};
14469
14469
14470
-
14471
14470
// High level grammar validation
14472
14471
for (auto *Child : LoopSeqStmt->children()) {
14473
14472
14474
- if (!Child)
14473
+ if (!Child)
14475
14474
continue;
14476
14475
14477
- // Skip over non-loop-sequence statements
14478
- if (!isLoopSequenceDerivation(Child)) {
14476
+ // Skip over non-loop-sequence statements
14477
+ if (!isLoopSequenceDerivation(Child)) {
14479
14478
Child = Child->IgnoreContainers();
14480
14479
14481
14480
// Ignore empty compound statement
@@ -14493,9 +14492,9 @@ bool SemaOpenMP::analyzeLoopSequence(
14493
14492
// Already been treated, skip this children
14494
14493
continue;
14495
14494
}
14496
- }
14497
- // Regular loop sequence handling
14498
- if (isLoopSequenceDerivation(Child)) {
14495
+ }
14496
+ // Regular loop sequence handling
14497
+ if (isLoopSequenceDerivation(Child)) {
14499
14498
if (isLoopGeneratingStmt(Child)) {
14500
14499
if (!analyzeLoopGeneration(Child)) {
14501
14500
return false;
@@ -14509,12 +14508,12 @@ bool SemaOpenMP::analyzeLoopSequence(
14509
14508
// Update the Loop Sequence size by one
14510
14509
++LoopSeqSize;
14511
14510
}
14512
- } else {
14511
+ } else {
14513
14512
// Report error for invalid statement inside canonical loop sequence
14514
14513
Diag(Child->getBeginLoc(), diag::err_omp_not_for)
14515
14514
<< 0 << getOpenMPDirectiveName(Kind);
14516
14515
return false;
14517
- }
14516
+ }
14518
14517
}
14519
14518
return true;
14520
14519
}
@@ -14531,9 +14530,9 @@ bool SemaOpenMP::checkTransformableLoopSequence(
14531
14530
14532
14531
// Checks whether the given statement is a compound statement
14533
14532
if (!isa<CompoundStmt>(AStmt)) {
14534
- Diag(AStmt->getBeginLoc(), diag::err_omp_not_a_loop_sequence)
14535
- << getOpenMPDirectiveName(Kind);
14536
- return false;
14533
+ Diag(AStmt->getBeginLoc(), diag::err_omp_not_a_loop_sequence)
14534
+ << getOpenMPDirectiveName(Kind);
14535
+ return false;
14537
14536
}
14538
14537
// Number of top level canonical loop nests observed (And acts as index)
14539
14538
LoopSeqSize = 0;
@@ -14564,7 +14563,7 @@ bool SemaOpenMP::checkTransformableLoopSequence(
14564
14563
OriginalInits, TransformsPreInits,
14565
14564
LoopSequencePreInits, LoopCategories, Context,
14566
14565
Kind)) {
14567
- return false;
14566
+ return false;
14568
14567
}
14569
14568
if (LoopSeqSize <= 0) {
14570
14569
Diag(AStmt->getBeginLoc(), diag::err_omp_empty_loop_sequence)
@@ -15278,7 +15277,7 @@ StmtResult SemaOpenMP::ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses,
15278
15277
Stmt *LoopStmt = nullptr;
15279
15278
collectLoopStmts(AStmt, {LoopStmt});
15280
15279
15281
- // Determine the PreInit declarations.e
15280
+ // Determine the PreInit declarations.
15282
15281
SmallVector<Stmt *, 4> PreInits;
15283
15282
addLoopPreInits(Context, LoopHelper, LoopStmt, OriginalInits[0], PreInits);
15284
15283
@@ -15894,13 +15893,18 @@ StmtResult SemaOpenMP::ActOnOpenMPFuseDirective(ArrayRef<OMPClause *> Clauses,
15894
15893
CountVal = CountInt.getZExtValue();
15895
15894
};
15896
15895
15897
- // Checks if the loop range is valid
15896
+ // OpenMP [6.0, Restrictions]
15897
+ // first + count - 1 must not evaluate to a value greater than the
15898
+ // loop sequence length of the associated canonical loop sequence.
15898
15899
auto ValidLoopRange = [](uint64_t FirstVal, uint64_t CountVal,
15899
15900
unsigned NumLoops) -> bool {
15900
15901
return FirstVal + CountVal - 1 <= NumLoops;
15901
15902
};
15902
15903
uint64_t FirstVal = 1, CountVal = 0, LastVal = LoopSeqSize;
15903
15904
15905
+ // Validates the loop range after evaluating the semantic information
15906
+ // and ensures that the range is valid for the given loop sequence size.
15907
+ // Expressions are evaluated at compile time to obtain constant values.
15904
15908
if (LRC) {
15905
15909
EvaluateLoopRangeArguments(LRC->getFirst(), LRC->getCount(), FirstVal,
15906
15910
CountVal);
0 commit comments