[flang-commits] [flang] [flang][OpenMP] Implicitly capture variables in enclosing task for nested firstprivate (PR #183770)

via flang-commits flang-commits at lists.llvm.org
Fri Feb 27 08:59:53 PST 2026


https://github.com/Ritanya-B-Bharadwaj created https://github.com/llvm/llvm-project/pull/183770

Fixes - https://github.com/llvm/llvm-project/issues/181271
When a variable appears in a firstprivate clause on a nested task but is not otherwise referenced in the enclosing task's body, the enclosing task must implicitly capture it as firstprivate. Without this, the nested task references the parallel region's stack frame, which may be destroyed before the deferred task executes, causing a use-after-free crash.

>From 419a685295a934f47db1a8894d0e419ea4f0e010 Mon Sep 17 00:00:00 2001
From: Ritanya B Bharadwaj <ritanya.b.bharadwaj at gmail.com>
Date: Fri, 27 Feb 2026 02:36:54 -0600
Subject: [PATCH] Fixing issue #181271

---
 flang/lib/Semantics/resolve-directives.cpp    |  6 +++++
 .../OpenMP/task-implicit-firstprivate.f90     | 25 +++++++++++++++++++
 2 files changed, 31 insertions(+)
 create mode 100644 flang/test/Lower/OpenMP/task-implicit-firstprivate.f90

diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 7e11be509cd02..22f66aafea941 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -3148,6 +3148,12 @@ void OmpAttributeVisitor::ResolveOmpDesignator(
         AddAllocateName(name);
       }
     }
+    // Save the original symbol. For privatizing clauses, ensure enclosing
+    // constructs properly capture the variable.
+    const Symbol *origSymbol{name->symbol};
+    if (origSymbol && privateDataSharingAttributeFlags.test(ompFlag)) {
+      CreateImplicitSymbols(origSymbol);
+    }
     if (ompFlag == Symbol::Flag::OmpReduction) {
       // Using variables inside of a namelist in OpenMP reductions
       // is allowed by the standard, but is not allowed for
diff --git a/flang/test/Lower/OpenMP/task-implicit-firstprivate.f90 b/flang/test/Lower/OpenMP/task-implicit-firstprivate.f90
new file mode 100644
index 0000000000000..ae37082b389b6
--- /dev/null
+++ b/flang/test/Lower/OpenMP/task-implicit-firstprivate.f90
@@ -0,0 +1,25 @@
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s
+
+! CHECK-LABEL: omp.private
+! CHECK-SAME:      {type = firstprivate} @[[B_FIRSTPRIVATE:.*firstprivate.*]] : !fir.box<!fir.array<2xi32>>
+
+! CHECK-LABEL: func @_QPtest_nested_task_firstprivate
+! CHECK:         omp.parallel
+! CHECK:           omp.task private(@[[B_FIRSTPRIVATE]] %{{.*}} -> %[[OUTER_TASK_B:.*]] :
+! CHECK:             %[[OUTER_TASK_B_DECL:.*]]:2 = hlfir.declare %[[OUTER_TASK_B]]
+! CHECK:             omp.task private(@[[B_FIRSTPRIVATE]] %[[OUTER_TASK_B_DECL]]#0 -> %[[INNER_TASK_B:.*]] :
+! CHECK:               hlfir.declare %[[INNER_TASK_B]]
+! CHECK:               omp.terminator
+! CHECK:             omp.terminator
+! CHECK:           omp.terminator
+subroutine test_nested_task_firstprivate
+  integer :: b(2)
+  b = 1
+  !$omp parallel private(b)
+    b = 2
+    !$omp task
+      !$omp task firstprivate(b)
+      !$omp end task
+    !$omp end task
+  !$omp end parallel
+end subroutine



More information about the flang-commits mailing list