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
