https://github.com/w007878 updated 
https://github.com/llvm/llvm-project/pull/199178

>From ad62385ed3789411409beaccdb9515f179cc8206 Mon Sep 17 00:00:00 2001
From: Fan Mo <[email protected]>
Date: Fri, 22 May 2026 01:42:44 -0500
Subject: [PATCH 1/4] fix: array type to avoid VLA reduction operand

---
 clang/lib/Sema/SemaOpenACC.cpp | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp
index a228d224e2308..48e43bfbc23bd 100644
--- a/clang/lib/Sema/SemaOpenACC.cpp
+++ b/clang/lib/Sema/SemaOpenACC.cpp
@@ -2688,6 +2688,14 @@ Expr *GenerateReductionInitRecipeExpr(ASTContext 
&Context,
         return nullptr;
     }
 
+  } else if (Ty->isArrayType()) {
+    // Non-constant arrays (VLAs and incomplete arrays) cannot be statically
+    // enumerated to build an InitListExpr.  
+    // Punt the same way we do for pointers below; codegen is responsible for
+    // handling these cases (or emitting a NYI). Without this, a 
variable-length
+    // array reduction operand falls through to the scalar branch and trips the
+    // 'isScalarType()' assertion (llvm/llvm-project#199162).
+    return nullptr;
   } else if (Ty->isPointerType()) {
     // For now, we are going to punt/not initialize pointer types, as
     // discussions/designs are ongoing on how to express this behavior,

>From 2bdd83184b008b2d42d026625c4948805b2babcc Mon Sep 17 00:00:00 2001
From: Fan Mo <[email protected]>
Date: Fri, 22 May 2026 01:46:42 -0500
Subject: [PATCH 2/4] fix: check ArrayType for OpenACC

---
 clang/lib/Sema/SemaOpenACC.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp
index 48e43bfbc23bd..c4c53a0213869 100644
--- a/clang/lib/Sema/SemaOpenACC.cpp
+++ b/clang/lib/Sema/SemaOpenACC.cpp
@@ -2690,7 +2690,7 @@ Expr *GenerateReductionInitRecipeExpr(ASTContext &Context,
 
   } else if (Ty->isArrayType()) {
     // Non-constant arrays (VLAs and incomplete arrays) cannot be statically
-    // enumerated to build an InitListExpr.  
+    // enumerated to build an InitListExpr.
     // Punt the same way we do for pointers below; codegen is responsible for
     // handling these cases (or emitting a NYI). Without this, a 
variable-length
     // array reduction operand falls through to the scalar branch and trips the

>From 4250bae10f9922428b3353c825282dd76716dc92 Mon Sep 17 00:00:00 2001
From: Fan Mo <[email protected]>
Date: Fri, 22 May 2026 01:54:25 -0500
Subject: [PATCH 3/4] add regression tests

---
 .../compute-construct-reduction-vla.c         | 70 ++++++++++++++
 .../compute-construct-reduction-vla.cpp       | 92 +++++++++++++++++++
 2 files changed, 162 insertions(+)
 create mode 100644 clang/test/SemaOpenACC/compute-construct-reduction-vla.c
 create mode 100644 clang/test/SemaOpenACC/compute-construct-reduction-vla.cpp

diff --git a/clang/test/SemaOpenACC/compute-construct-reduction-vla.c 
b/clang/test/SemaOpenACC/compute-construct-reduction-vla.c
new file mode 100644
index 0000000000000..f51f28d3751ca
--- /dev/null
+++ b/clang/test/SemaOpenACC/compute-construct-reduction-vla.c
@@ -0,0 +1,70 @@
+// RUN: %clang_cc1 %s -fopenacc -verify
+
+// Regression test for llvm/llvm-project#199162:
+//
+// A variable-length array operand to an OpenACC 'reduction' clause used to
+// trip the assertion `Ty->isScalarType()` inside
+// GenerateReductionInitRecipeExpr (clang/lib/Sema/SemaOpenACC.cpp).
+//
+// VLAs cannot be statically enumerated to build an InitListExpr, so we now
+// punt (the same way we already do for pointer types) and let codegen handle
+// it.  This test makes sure none of the variations below crash in Sema and
+// that they parse cleanly without spurious diagnostics.
+
+// expected-no-diagnostics
+
+void vla_reduction_bitand(int i) {
+  int arr[i + 1];
+#pragma acc parallel reduction(& : arr)
+  while (1)
+    ;
+}
+
+void vla_reduction_add(int i) {
+  int arr[i + 1];
+#pragma acc parallel reduction(+ : arr)
+  while (1)
+    ;
+}
+
+void vla_reduction_max(int i) {
+  int arr[i + 1];
+#pragma acc parallel reduction(max : arr)
+  while (1)
+    ;
+}
+
+void vla_reduction_min(int i) {
+  int arr[i + 1];
+#pragma acc parallel reduction(min : arr)
+  while (1)
+    ;
+}
+
+void vla_reduction_mul(int i) {
+  int arr[i + 1];
+#pragma acc parallel reduction(* : arr)
+  while (1)
+    ;
+}
+
+void vla_reduction_bitor(int i) {
+  unsigned arr[i + 1];
+#pragma acc parallel reduction(| : arr)
+  while (1)
+    ;
+}
+
+void vla_reduction_bitxor(int i) {
+  unsigned arr[i + 1];
+#pragma acc parallel reduction(^ : arr)
+  while (1)
+    ;
+}
+
+void vla_reduction_serial(int i) {
+  int arr[i + 1];
+#pragma acc serial reduction(| : arr)
+  while (1)
+    ;
+}
diff --git a/clang/test/SemaOpenACC/compute-construct-reduction-vla.cpp 
b/clang/test/SemaOpenACC/compute-construct-reduction-vla.cpp
new file mode 100644
index 0000000000000..f1b13384dcb03
--- /dev/null
+++ b/clang/test/SemaOpenACC/compute-construct-reduction-vla.cpp
@@ -0,0 +1,92 @@
+// RUN: %clang_cc1 %s -fopenacc -verify -Wno-vla-cxx-extension
+
+// C++ companion to compute-construct-reduction-vla.c.
+//
+// Regression test for llvm/llvm-project#199162.  The original reproducer in
+// that issue was driven through clang++, so we keep an explicit C++
+// counterpart that exercises the same Sema path on:
+//   * a bare VLA declared in a function body (clang accepts as a GNU
+//     extension in C++; gated by -Wno-vla-cxx-extension above),
+//   * references to VLAs,
+//   * VLAs reached through a function template (dependent then concrete
+//     after instantiation),
+//   * an array section over a VLA.
+//
+// All cases must parse cleanly without crashing in
+// GenerateReductionInitRecipeExpr.
+
+// expected-no-diagnostics
+
+void vla_reduction_bitand_cxx(int i) {
+  int arr[i + 1];
+#pragma acc parallel reduction(& : arr)
+  while (1)
+    ;
+}
+
+void vla_reduction_add_cxx(int i) {
+  int arr[i + 1];
+#pragma acc parallel reduction(+ : arr)
+  while (1)
+    ;
+}
+
+void vla_reduction_serial_cxx(int i) {
+  unsigned arr[i + 1];
+#pragma acc serial reduction(| : arr)
+  while (1)
+    ;
+}
+
+// A reference binding to a VLA — VarTy after getNonReferenceType() is
+// still a VariableArrayType, so the recipe builder runs the same path.
+void vla_reduction_reference(int i) {
+  int storage[i + 1];
+  int(&arr)[i + 1] = storage;
+#pragma acc parallel reduction(+ : arr)
+  while (1)
+    ;
+}
+
+// Template — the VLA size depends on a non-type template parameter, so
+// the operand type is dependent at template-definition time and
+// CreateReductionInitRecipe should bail out early via the
+// isDependentType() guard.  After instantiation the type becomes
+// concrete (still a VLA: the runtime size depends on 'n' below), and
+// the recipe builder runs the punt branch we added.
+template <int Pad>
+void vla_reduction_template(int n) {
+  int arr[n + Pad];
+#pragma acc parallel reduction(+ : arr)
+  while (1)
+    ;
+}
+
+void instantiate_template(int n) {
+  vla_reduction_template<1>(n);
+  vla_reduction_template<8>(n);
+}
+
+// 2D VLA, in C++.
+void vla_reduction_2d_cxx(int i, int j) {
+  int arr[i + 1][j + 1];
+#pragma acc parallel reduction(+ : arr)
+  while (1)
+    ;
+}
+
+// Array section on a VLA, in C++.
+void vla_reduction_array_section_cxx(int i) {
+  int arr[i + 1];
+#pragma acc parallel reduction(+ : arr[0:i])
+  while (1)
+    ;
+}
+
+// Combined construct.
+void vla_reduction_combined_cxx(int i) {
+  int arr[i + 1];
+#pragma acc parallel loop reduction(+ : arr)
+  for (int k = 0; k < 10; ++k)
+    ;
+}

>From 73c50a377a8f064b04987724fb950f6768e5be93 Mon Sep 17 00:00:00 2001
From: Fan Mo <[email protected]>
Date: Sun, 24 May 2026 01:00:18 -0400
Subject: [PATCH 4/4] reject VLA and consolidate tests

---
 .../clang/Basic/DiagnosticSemaKinds.td        |  3 +
 clang/lib/Sema/SemaOpenACC.cpp                |  8 --
 clang/lib/Sema/SemaOpenACCClause.cpp          |  6 ++
 .../compute-construct-reduction-vla.c         | 66 ++--------------
 .../compute-construct-reduction-vla.cpp       | 76 ++++---------------
 5 files changed, 30 insertions(+), 129 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index dbe6cb2c3a41c..80ca61491eca6 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -14002,6 +14002,9 @@ def note_acc_reduction_type_summary
            "or a "
            "composite of scalars, or an array, sub-array, or element of scalar 
"
            "types">;
+def err_acc_reduction_vla
+    : Error<"variable length array cannot be used in OpenACC 'reduction' "
+            "clause">;
 def err_acc_loop_not_for_loop
     : Error<"OpenACC '%0' construct can only be applied to a 'for' loop">;
 def note_acc_construct_here : Note<"'%0' construct is here">;
diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp
index 981e8169dbe4e..79edb8093c368 100644
--- a/clang/lib/Sema/SemaOpenACC.cpp
+++ b/clang/lib/Sema/SemaOpenACC.cpp
@@ -2689,14 +2689,6 @@ Expr *GenerateReductionInitRecipeExpr(ASTContext 
&Context,
         return nullptr;
     }
 
-  } else if (Ty->isArrayType()) {
-    // Non-constant arrays (VLAs and incomplete arrays) cannot be statically
-    // enumerated to build an InitListExpr.
-    // Punt the same way we do for pointers below; codegen is responsible for
-    // handling these cases (or emitting a NYI). Without this, a 
variable-length
-    // array reduction operand falls through to the scalar branch and trips the
-    // 'isScalarType()' assertion (llvm/llvm-project#199162).
-    return nullptr;
   } else if (Ty->isPointerType()) {
     // For now, we are going to punt/not initialize pointer types, as
     // discussions/designs are ongoing on how to express this behavior,
diff --git a/clang/lib/Sema/SemaOpenACCClause.cpp 
b/clang/lib/Sema/SemaOpenACCClause.cpp
index c27c05c137eab..186fa7a0830d4 100644
--- a/clang/lib/Sema/SemaOpenACCClause.cpp
+++ b/clang/lib/Sema/SemaOpenACCClause.cpp
@@ -1898,6 +1898,12 @@ bool SemaOpenACC::CheckReductionVarType(Expr *VarExpr) {
   // array.  The standard isn't clear here whether this is allowed, but
   // array-of-valid-things makes sense.
   if (auto *AT = getASTContext().getAsArrayType(CurType)) {
+    // Reject VLA as reduction type, as we don't have any reasonable IR to 
generate
+    // See https://github.com/llvm/llvm-project/issues/199162
+    if (isa<VariableArrayType>(AT)) {
+      Diag(VarLoc, diag::err_acc_reduction_vla);
+      return true;
+    }
     // If we're already the array type, peel off the array and leave the 
element
     // type.
     PartialDiagnostic PD = PDiag(diag::note_acc_reduction_array)
diff --git a/clang/test/SemaOpenACC/compute-construct-reduction-vla.c 
b/clang/test/SemaOpenACC/compute-construct-reduction-vla.c
index f51f28d3751ca..3801197245ea2 100644
--- a/clang/test/SemaOpenACC/compute-construct-reduction-vla.c
+++ b/clang/test/SemaOpenACC/compute-construct-reduction-vla.c
@@ -1,70 +1,20 @@
 // RUN: %clang_cc1 %s -fopenacc -verify
 
 // Regression test for llvm/llvm-project#199162:
-//
-// A variable-length array operand to an OpenACC 'reduction' clause used to
-// trip the assertion `Ty->isScalarType()` inside
-// GenerateReductionInitRecipeExpr (clang/lib/Sema/SemaOpenACC.cpp).
-//
-// VLAs cannot be statically enumerated to build an InitListExpr, so we now
-// punt (the same way we already do for pointer types) and let codegen handle
-// it.  This test makes sure none of the variations below crash in Sema and
-// that they parse cleanly without spurious diagnostics.
+// Variable-length arrays cannot be used in OpenACC 'reduction' clauses.
 
-// expected-no-diagnostics
-
-void vla_reduction_bitand(int i) {
-  int arr[i + 1];
-#pragma acc parallel reduction(& : arr)
-  while (1)
-    ;
-}
-
-void vla_reduction_add(int i) {
-  int arr[i + 1];
+void vla_reduction(int n) {
+  int arr[n];
+  // expected-error@+1{{variable length array cannot be used in OpenACC 
'reduction' clause}}
 #pragma acc parallel reduction(+ : arr)
   while (1)
     ;
 }
 
-void vla_reduction_max(int i) {
-  int arr[i + 1];
-#pragma acc parallel reduction(max : arr)
-  while (1)
-    ;
-}
-
-void vla_reduction_min(int i) {
-  int arr[i + 1];
-#pragma acc parallel reduction(min : arr)
-  while (1)
-    ;
-}
-
-void vla_reduction_mul(int i) {
-  int arr[i + 1];
-#pragma acc parallel reduction(* : arr)
-  while (1)
-    ;
-}
-
-void vla_reduction_bitor(int i) {
-  unsigned arr[i + 1];
-#pragma acc parallel reduction(| : arr)
-  while (1)
-    ;
-}
-
-void vla_reduction_bitxor(int i) {
-  unsigned arr[i + 1];
-#pragma acc parallel reduction(^ : arr)
-  while (1)
-    ;
-}
-
-void vla_reduction_serial(int i) {
-  int arr[i + 1];
-#pragma acc serial reduction(| : arr)
+void vla_reduction_serial(int n) {
+  int arr[n];
+  // expected-error@+1{{variable length array cannot be used in OpenACC 
'reduction' clause}}
+#pragma acc serial reduction(& : arr)
   while (1)
     ;
 }
diff --git a/clang/test/SemaOpenACC/compute-construct-reduction-vla.cpp 
b/clang/test/SemaOpenACC/compute-construct-reduction-vla.cpp
index f1b13384dcb03..6507ba4a7f44d 100644
--- a/clang/test/SemaOpenACC/compute-construct-reduction-vla.cpp
+++ b/clang/test/SemaOpenACC/compute-construct-reduction-vla.cpp
@@ -1,91 +1,41 @@
 // RUN: %clang_cc1 %s -fopenacc -verify -Wno-vla-cxx-extension
 
 // C++ companion to compute-construct-reduction-vla.c.
-//
-// Regression test for llvm/llvm-project#199162.  The original reproducer in
-// that issue was driven through clang++, so we keep an explicit C++
-// counterpart that exercises the same Sema path on:
-//   * a bare VLA declared in a function body (clang accepts as a GNU
-//     extension in C++; gated by -Wno-vla-cxx-extension above),
-//   * references to VLAs,
-//   * VLAs reached through a function template (dependent then concrete
-//     after instantiation),
-//   * an array section over a VLA.
-//
-// All cases must parse cleanly without crashing in
-// GenerateReductionInitRecipeExpr.
+// Regression test for llvm/llvm-project#199162.
 
-// expected-no-diagnostics
-
-void vla_reduction_bitand_cxx(int i) {
-  int arr[i + 1];
-#pragma acc parallel reduction(& : arr)
-  while (1)
-    ;
-}
-
-void vla_reduction_add_cxx(int i) {
-  int arr[i + 1];
+void vla_reduction_cxx(int n) {
+  int arr[n];
+  // expected-error@+1{{variable length array cannot be used in OpenACC 
'reduction' clause}}
 #pragma acc parallel reduction(+ : arr)
   while (1)
     ;
 }
 
-void vla_reduction_serial_cxx(int i) {
-  unsigned arr[i + 1];
-#pragma acc serial reduction(| : arr)
-  while (1)
-    ;
-}
-
-// A reference binding to a VLA — VarTy after getNonReferenceType() is
-// still a VariableArrayType, so the recipe builder runs the same path.
-void vla_reduction_reference(int i) {
-  int storage[i + 1];
-  int(&arr)[i + 1] = storage;
+void vla_reduction_reference(int n) {
+  int storage[n];
+  int(&arr)[n] = storage;
+  // expected-error@+1{{variable length array cannot be used in OpenACC 
'reduction' clause}}
 #pragma acc parallel reduction(+ : arr)
   while (1)
     ;
 }
 
-// Template — the VLA size depends on a non-type template parameter, so
-// the operand type is dependent at template-definition time and
-// CreateReductionInitRecipe should bail out early via the
-// isDependentType() guard.  After instantiation the type becomes
-// concrete (still a VLA: the runtime size depends on 'n' below), and
-// the recipe builder runs the punt branch we added.
 template <int Pad>
 void vla_reduction_template(int n) {
   int arr[n + Pad];
+  // expected-error@+1{{variable length array cannot be used in OpenACC 
'reduction' clause}}
 #pragma acc parallel reduction(+ : arr)
   while (1)
     ;
 }
 
 void instantiate_template(int n) {
-  vla_reduction_template<1>(n);
-  vla_reduction_template<8>(n);
-}
-
-// 2D VLA, in C++.
-void vla_reduction_2d_cxx(int i, int j) {
-  int arr[i + 1][j + 1];
-#pragma acc parallel reduction(+ : arr)
-  while (1)
-    ;
-}
-
-// Array section on a VLA, in C++.
-void vla_reduction_array_section_cxx(int i) {
-  int arr[i + 1];
-#pragma acc parallel reduction(+ : arr[0:i])
-  while (1)
-    ;
+  vla_reduction_template<1>(n); // expected-note{{in instantiation of function 
template specialization}}
 }
 
-// Combined construct.
-void vla_reduction_combined_cxx(int i) {
-  int arr[i + 1];
+void vla_reduction_combined(int n) {
+  int arr[n];
+  // expected-error@+1{{variable length array cannot be used in OpenACC 
'reduction' clause}}
 #pragma acc parallel loop reduction(+ : arr)
   for (int k = 0; k < 10; ++k)
     ;

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

Reply via email to