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@-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