[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 09:00:26 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-fir-hlfir
Author: None (Ritanya-B-Bharadwaj)
<details>
<summary>Changes</summary>
Fixes - https://github.com/llvm/llvm-project/issues/181271
If a variable is marked firstprivate in a nested task but not actually used in the outer task body, we still need the outer task to capture it as firstprivate. Otherwise the nested task can end up pointing to the parallel region’s stack frame, which might already be gone when the deferred task runs — causing a use-after-free.
---
Full diff: https://github.com/llvm/llvm-project/pull/183770.diff
2 Files Affected:
- (modified) flang/lib/Semantics/resolve-directives.cpp (+6)
- (added) flang/test/Lower/OpenMP/task-implicit-firstprivate.f90 (+25)
``````````diff
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
``````````
</details>
https://github.com/llvm/llvm-project/pull/183770
More information about the flang-commits
mailing list