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/7] 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/7] 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/7] 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/7] 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) ; >From c7674acd998c516f0fb24d603f1acbd8163237f9 Mon Sep 17 00:00:00 2001 From: Fan Mo <[email protected]> Date: Sun, 24 May 2026 01:08:25 -0400 Subject: [PATCH 5/7] check original type --- clang/lib/Sema/SemaOpenACCClause.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/clang/lib/Sema/SemaOpenACCClause.cpp b/clang/lib/Sema/SemaOpenACCClause.cpp index 186fa7a0830d4..5e745725e7958 100644 --- a/clang/lib/Sema/SemaOpenACCClause.cpp +++ b/clang/lib/Sema/SemaOpenACCClause.cpp @@ -1894,16 +1894,17 @@ bool SemaOpenACC::CheckReductionVarType(Expr *VarExpr) { if (CurType.isNull()) return false; + // Reject VLAs in reduction clauses since lowering is unsupported. + // See https://github.com/llvm/llvm-project/issues/199162 + if (CurType->isVariableArrayType()) { + Diag(VarLoc, diag::err_acc_reduction_vla); + return true; + } + // If we are still an array type, we allow 1 level of 'unpeeling' of the // 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) >From 4f485fca19f82d3d120965bae9b71c3a1aedaa99 Mon Sep 17 00:00:00 2001 From: Fan Mo <[email protected]> Date: Sun, 24 May 2026 01:09:06 -0400 Subject: [PATCH 6/7] fix: not pointer --- clang/lib/Sema/SemaOpenACCClause.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaOpenACCClause.cpp b/clang/lib/Sema/SemaOpenACCClause.cpp index 5e745725e7958..e91308173c86b 100644 --- a/clang/lib/Sema/SemaOpenACCClause.cpp +++ b/clang/lib/Sema/SemaOpenACCClause.cpp @@ -1896,7 +1896,7 @@ bool SemaOpenACC::CheckReductionVarType(Expr *VarExpr) { // Reject VLAs in reduction clauses since lowering is unsupported. // See https://github.com/llvm/llvm-project/issues/199162 - if (CurType->isVariableArrayType()) { + if (CurType.isVariableArrayType()) { Diag(VarLoc, diag::err_acc_reduction_vla); return true; } >From 1b0a6e5f3eca8e69ecc2efae7773f46ac94a67bb Mon Sep 17 00:00:00 2001 From: Fan Mo <[email protected]> Date: Sun, 24 May 2026 01:12:28 -0400 Subject: [PATCH 7/7] Revert "fix: not pointer" This reverts commit 4f485fca19f82d3d120965bae9b71c3a1aedaa99. --- clang/lib/Sema/SemaOpenACCClause.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaOpenACCClause.cpp b/clang/lib/Sema/SemaOpenACCClause.cpp index e91308173c86b..5e745725e7958 100644 --- a/clang/lib/Sema/SemaOpenACCClause.cpp +++ b/clang/lib/Sema/SemaOpenACCClause.cpp @@ -1896,7 +1896,7 @@ bool SemaOpenACC::CheckReductionVarType(Expr *VarExpr) { // Reject VLAs in reduction clauses since lowering is unsupported. // See https://github.com/llvm/llvm-project/issues/199162 - if (CurType.isVariableArrayType()) { + if (CurType->isVariableArrayType()) { Diag(VarLoc, diag::err_acc_reduction_vla); return true; } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
