https://github.com/Karthikdhondi updated 
https://github.com/llvm/llvm-project/pull/182480

>From bb730f12cc3acda5d4025910043407c74ad90f60 Mon Sep 17 00:00:00 2001
From: "karthik.dhondi" <[email protected]>
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. And also for direct VLA, lvalue/rvalue references to VLAs, and 
multidimensional pointer-to-VLA.

Fixes #177608
---
 clang/lib/CodeGen/CGStmtOpenMP.cpp            | 18 ++++++++
 .../parallel-pointer-to-vla-auto-ref.cpp      | 46 +++++++++++++++++++
 .../OpenMP/parallel-pointer-to-vla-auto.c     | 26 +++++++++++
 3 files changed, 90 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 1eaf8efa142c5..c75ea1cee68d6 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -860,6 +860,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..f2011c25f1e29
--- /dev/null
+++ b/clang/test/OpenMP/parallel-pointer-to-vla-auto-ref.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -std=c++20 -emit-llvm %s -o %t.ll
+// RUN: %clang_cc1 -fopenmp -std=c++20 -emit-llvm %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;
+}
+
+// Direct VLA capture.
+void direct_vla(int N) {
+  int arr[N];
+
+  #pragma omp parallel for
+  for (int i = 0; i < N; ++i)
+    arr[i] = i;
+}
+
+// Lvalue reference to VLA.
+void lvalue_ref_vla(int N, int (&arr)[N]) {
+  auto &ref = arr;
+
+  #pragma omp parallel for
+  for (int i = 0; i < N; ++i)
+    ref[i] = i;
+}
+
+// Rvalue reference to VLA.
+void rvalue_ref_vla(int N, int (&&arr)[N]) {
+  auto &&ref = arr;
+
+  #pragma omp parallel for
+  for (int i = 0; i < N; ++i)
+    ref[i] = i;
+}
+
+// Pointer to 2D VLA.
+void ptr_to_2d_vla(int N, int M, int (*p)[N][M]) {
+  auto &ref = p;
+
+  #pragma omp parallel for
+  for (int i = 0; i < N; ++i)
+    (*ref)[i][i % M] = i;
+}
+
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..5521679ae94ed
--- /dev/null
+++ b/clang/test/OpenMP/parallel-pointer-to-vla-auto.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -std=c23 -emit-llvm %s -o %t.ll
+// RUN: %clang_cc1 -fopenmp -std=c23 -emit-llvm %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;
+}

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

Reply via email to