[clang] [Clang][OpenMP] Fix crash with captured pointer-to-VLA in outlined re… (PR #182480)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Feb 20 05:21:07 PST 2026
https://github.com/Karthikdhondi updated https://github.com/llvm/llvm-project/pull/182480
>From 2492ef2e737964323350ac11f8906435e3957516 Mon Sep 17 00:00:00 2001
From: "karthik.dhondi" <karthik.dhondi at gmail.com>
Date: Fri, 20 Feb 2026 17:04:11 +0530
Subject: [PATCH] [Clang][OpenMP] Fix crash with captured pointer-to-VLA in
outlined regions
Ensure VLA size expressions are emitted for captured pointer-to-VLA
variables (including reference cases) before outlining. Previously this
could trigger an assertion in getVLASize() during code generation.
Add regression tests for C23 auto, __auto_type, explicit casts, and C++
reference cases.
Fixes #177608
---
clang/lib/CodeGen/CGStmtOpenMP.cpp | 18 +++++++++++++
.../parallel-pointer-to-vla-auto-ref.cpp | 9 +++++++
.../OpenMP/parallel-pointer-to-vla-auto.c | 26 +++++++++++++++++++
3 files changed, 53 insertions(+)
create mode 100644 clang/test/OpenMP/parallel-pointer-to-vla-auto-ref.cpp
create mode 100644 clang/test/OpenMP/parallel-pointer-to-vla-auto.c
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index ea89db5471089..2ed54f0a5e0f1 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -745,6 +745,24 @@ llvm::Function *CodeGenFunction::GenerateOpenMPCapturedStmtFunction(
(void)LocalScope.Privatize();
for (const auto &VLASizePair : WrapperVLASizes)
VLASizeMap[VLASizePair.second.first] = VLASizePair.second.second;
+
+ for (const CapturedStmt::Capture &Cap : S.captures()) {
+ if (!Cap.capturesVariable())
+ continue;
+
+ const VarDecl *VD = Cap.getCapturedVar();
+ QualType Ty = VD->getType();
+
+ if (Ty->isReferenceType())
+ Ty = Ty->getPointeeType();
+
+ if (const PointerType *PT = Ty->getAs<PointerType>()) {
+ QualType PointeeTy = PT->getPointeeType();
+ if (PointeeTy->isVariablyModifiedType())
+ EmitVariablyModifiedType(PointeeTy);
+ }
+ }
+
PGO->assignRegionCounters(GlobalDecl(CD), F);
CapturedStmtInfo->EmitBody(*this, CD->getBody());
LocalScope.ForceCleanup();
diff --git a/clang/test/OpenMP/parallel-pointer-to-vla-auto-ref.cpp b/clang/test/OpenMP/parallel-pointer-to-vla-auto-ref.cpp
new file mode 100644
index 0000000000000..ee272e028038c
--- /dev/null
+++ b/clang/test/OpenMP/parallel-pointer-to-vla-auto-ref.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang -x c++ -std=c++20 -emit-llvm -S %s -o %t.ll
+// RUN: %clang -x c++ -fopenmp -std=c++20 -emit-llvm -S %s -o %t.ll
+
+void bar(int N, int (*arr_)[N][N]) {
+ auto &ref = arr_; // reference to pointer-to-VLA
+ #pragma omp parallel for
+ for (int i = 0; i < N; ++i)
+ (*ref)[i][i] = 1;
+}
diff --git a/clang/test/OpenMP/parallel-pointer-to-vla-auto.c b/clang/test/OpenMP/parallel-pointer-to-vla-auto.c
new file mode 100644
index 0000000000000..b1a0dbcdf3442
--- /dev/null
+++ b/clang/test/OpenMP/parallel-pointer-to-vla-auto.c
@@ -0,0 +1,26 @@
+// RUN: %clang -std=c23 -emit-llvm -S %s -o %t.ll
+// RUN: %clang -fopenmp -std=c23 -emit-llvm -S %s -o %t.ll
+
+// Case 1: C23 auto
+void foo1(int N, int (*arr_)[N][N]) {
+ auto arr = arr_;
+ #pragma omp parallel for
+ for (int n = 0; n < N; ++n)
+ (*arr)[n][n] = 1;
+}
+
+// Case 2: GNU __auto_type
+void foo2(int N, int (*arr_)[N][N]) {
+ __auto_type arr = arr_;
+ #pragma omp parallel for
+ for (int n = 0; n < N; ++n)
+ (*arr)[n][n] = 1;
+}
+
+// Case 3: auto with explicit cast
+void foo3(int N, int (*arr_)[N][N]) {
+ auto arr = (int (*)[N][N])arr_;
+ #pragma omp parallel for
+ for (int n = 0; n < N; ++n)
+ (*arr)[n][n] = 1;
+}
More information about the cfe-commits
mailing list