https://github.com/loopacino created 
https://github.com/llvm/llvm-project/pull/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.

>From b54425f256d1c4c6c9e52b0025939431cddcd69c Mon Sep 17 00:00:00 2001
From: amtiwari <[email protected]>
Date: Mon, 21 Sep 2026 05:34:09 -0400
Subject: [PATCH] delay_folding_till_instantiation

---
 clang/lib/Sema/SemaOpenMP.cpp                 |  4 +-
 ...llapse_ordered_instantiation_dependent.cpp | 52 +++++++++++++++++++
 2 files changed, 54 insertions(+), 2 deletions(-)
 create mode 100644 
clang/test/OpenMP/collapse_ordered_instantiation_dependent.cpp

diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 2e4d9f2f82f0b..c5222dc7d5e6f 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@-1 {{in instantiation of function template specialization 
'collapse_too_few<int>' requested here}}
+  ordered_too_few<int>();
+  // expected-note@-1 {{in instantiation of function template specialization 
'ordered_too_few<int>' requested here}}
+  collapse_literal_too_few<int>();
+  collapse_enough<int>();
+}

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to