[clang] d11b9ad - [Clang][OpenMP] Delay `collapse/ordered` nest walk until instantiation (#225052)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 21 22:07:46 PDT 2026
Author: Amit Tiwari
Date: 2026-09-22T10:37:40+05:30
New Revision: d11b9adc9bd2a1c8142ff134d04275c4cfce34b0
URL: https://github.com/llvm/llvm-project/commit/d11b9adc9bd2a1c8142ff134d04275c4cfce34b0
DIFF: https://github.com/llvm/llvm-project/commit/d11b9adc9bd2a1c8142ff134d04275c4cfce34b0.diff
LOG: [Clang][OpenMP] Delay `collapse/ordered` nest walk until instantiation (#225052)
Do not fold `collapse` and `ordered` counts in `checkOpenMPLoop` until
the expression is no longer instantiation-dependent.
Clause parsing already waits. The loop walker did not. A count like
`sizeof(sizeof(T() + T()))` was folded in the template, so Clang could
walk the wrong number of loops before instantiation.
Added:
clang/test/OpenMP/collapse_ordered_instantiation_dependent.cpp
Modified:
clang/lib/Sema/SemaOpenMP.cpp
Removed:
################################################################################
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index ae3d6653442d2..c6c8e71abaf5f 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -10200,7 +10200,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
if (CollapseLoopCountExpr) {
// Found 'collapse' clause - calculate collapse number.
Expr::EvalResult Result;
- if (!CollapseLoopCountExpr->isValueDependent() &&
+ if (!CollapseLoopCountExpr->isInstantiationDependent() &&
CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
NestedLoopCount = Result.Val.getInt().getLimitedValue();
@@ -10215,7 +10215,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
if (OrderedLoopCountExpr) {
// Found 'ordered' clause - calculate collapse number.
Expr::EvalResult EVResult;
- if (!OrderedLoopCountExpr->isValueDependent() &&
+ if (!OrderedLoopCountExpr->isInstantiationDependent() &&
OrderedLoopCountExpr->EvaluateAsInt(EVResult,
SemaRef.getASTContext())) {
llvm::APSInt Result = EVResult.Val.getInt();
diff --git a/clang/test/OpenMP/collapse_ordered_instantiation_dependent.cpp b/clang/test/OpenMP/collapse_ordered_instantiation_dependent.cpp
new file mode 100644
index 0000000000000..06c85ea805eac
--- /dev/null
+++ b/clang/test/OpenMP/collapse_ordered_instantiation_dependent.cpp
@@ -0,0 +1,52 @@
+// Check that collapse/ordered nest counts wait on instantiation-dependent
+// expressions, not only value-dependent ones.
+// sizeof(sizeof(T() + T())) names T, so it is instantiation-dependent, but
+// its value is already sizeof(size_t).
+//
+// RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -fopenmp %s
+// RUN: %clang_cc1 -verify -triple x86_64-pc-linux-gnu -fopenmp-simd %s
+
+template <typename T>
+void collapse_too_few() {
+#pragma omp for collapse(sizeof(sizeof(T() + T()))) // expected-note {{as specified in 'collapse' clause}}
+ for (int i = 0; i < 4; ++i)
+ ; // expected-error {{expected 8 for loops after '#pragma omp for', but found only 1}}
+}
+
+template <typename T>
+void ordered_too_few() {
+#pragma omp for ordered(sizeof(sizeof(T() + T()))) // expected-note {{as specified in 'ordered' clause}}
+ for (int i = 0; i < 4; ++i)
+ ; // expected-error {{expected 8 for loops after '#pragma omp for', but found only 1}}
+}
+
+// A literal count is not instantiation-dependent. Diagnose in the template.
+template <typename T>
+void collapse_literal_too_few() {
+#pragma omp for collapse(2) // expected-note {{as specified in 'collapse' clause}}
+ for (int i = 0; i < 4; ++i)
+ ; // expected-error {{expected 2 for loops after '#pragma omp for', but found only 1}}
+}
+
+template <typename T>
+void collapse_enough() {
+#pragma omp for collapse(sizeof(sizeof(T() + T())))
+ for (int i0 = 0; i0 < 2; ++i0)
+ for (int i1 = 0; i1 < 2; ++i1)
+ for (int i2 = 0; i2 < 2; ++i2)
+ for (int i3 = 0; i3 < 2; ++i3)
+ for (int i4 = 0; i4 < 2; ++i4)
+ for (int i5 = 0; i5 < 2; ++i5)
+ for (int i6 = 0; i6 < 2; ++i6)
+ for (int i7 = 0; i7 < 2; ++i7)
+ ;
+}
+
+void instantiate() {
+ collapse_too_few<int>();
+ // expected-note at -1 {{in instantiation of function template specialization 'collapse_too_few<int>' requested here}}
+ ordered_too_few<int>();
+ // expected-note at -1 {{in instantiation of function template specialization 'ordered_too_few<int>' requested here}}
+ collapse_literal_too_few<int>();
+ collapse_enough<int>();
+}
More information about the cfe-commits
mailing list