[flang-commits] [flang] [flang][OpenMP] Fix non-delayed privatization of dummy proc pointers (PR #232752)
via flang-commits
flang-commits at lists.llvm.org
Fri Oct 16 06:49:30 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-openmp
@llvm/pr-subscribers-flang-fir-hlfir
Author: Leandro Lupori (luporl)
<details>
<summary>Changes</summary>
Dummy procedure pointer arguments use an untyped
`!fir.boxproc<() -> ()>`, while other procedure pointer variables use
a typed `fir.boxproc`. This caused a type mismatch when using
firstprivate/lastprivate in SECTIONS, which doesn't use delayed
privatization.
Fix this by assigning to the privatized copy the same type as the
original variable's storage.
Fixes #<!-- -->197395
Assisted-By: Claude Opus 5.5
---
Full diff: https://github.com/llvm/llvm-project/pull/232752.diff
2 Files Affected:
- (modified) flang/lib/Lower/Bridge.cpp (+15-5)
- (modified) flang/test/Lower/OpenMP/privatization-proc-ptr.f90 (+31)
``````````diff
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 12a27771d432ce..d4ed16a2ee4cca 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -960,14 +960,24 @@ class FirConverter : public Fortran::lower::AbstractConverter {
Fortran::lower::SymbolBox hsb =
lookupSymbol(hsym, /*symMap=*/nullptr, /*forceHlfirBase=*/true);
+ mlir::Type allocType =
+ Fortran::semantics::IsAllocatableOrObjectPointer(&hsym.GetUltimate())
+ ? hSymType
+ : symType;
+ // The type of a procedure pointer depends on how the original was created:
+ // dummy procedure pointers use an untyped `!fir.boxproc<() -> ()>`, while
+ // other procedure pointers carry their interface signature.
+ // Give the clone the same type as the original storage so that copies
+ // between them do not mix boxproc types.
+ if (Fortran::semantics::IsProcedurePointer(hsym.GetUltimate()))
+ if (mlir::Value hostAddr = hsb.getAddr())
+ allocType = fir::unwrapRefType(hostAddr.getType());
+
auto allocate = [&](llvm::ArrayRef<mlir::Value> shape,
llvm::ArrayRef<mlir::Value> typeParams) -> mlir::Value {
mlir::Value allocVal = builder->allocateLocal(
- loc,
- Fortran::semantics::IsAllocatableOrObjectPointer(&hsym.GetUltimate())
- ? hSymType
- : symType,
- mangleName(sym), toStringRef(sym.GetUltimate().name()),
+ loc, allocType, mangleName(sym),
+ toStringRef(sym.GetUltimate().name()),
/*pinned=*/true, shape, typeParams,
sym.GetUltimate().attrs().test(Fortran::semantics::Attr::TARGET));
return allocVal;
diff --git a/flang/test/Lower/OpenMP/privatization-proc-ptr.f90 b/flang/test/Lower/OpenMP/privatization-proc-ptr.f90
index 61e10734fd4a07..5e0795689b7fb1 100644
--- a/flang/test/Lower/OpenMP/privatization-proc-ptr.f90
+++ b/flang/test/Lower/OpenMP/privatization-proc-ptr.f90
@@ -111,6 +111,37 @@ subroutine test_sections
!$omp end sections
end subroutine
+! Dummy procedure pointers are stored as an untyped !fir.boxproc<() -> ()>.
+! Their private copies must use the same type so that the firstprivate and
+! lastprivate copies are type consistent.
+!CHECK-LABEL: func private @_QFPtest_sections_dummy
+!CHECK-SAME: %[[ARG_PF:[^:]*]]: !fir.ref<!fir.boxproc<() -> ()>>
+!CHECK-SAME: %[[ARG_PS:[^:]*]]: !fir.ref<!fir.boxproc<() -> ()>>
+!CHECK: %[[PF:.*]]:2 = hlfir.declare %[[ARG_PF]] {{.*}}uniq_name("_QFFtest_sections_dummyEpf")
+!CHECK: %[[PS:.*]]:2 = hlfir.declare %[[ARG_PS]] {{.*}}uniq_name("_QFFtest_sections_dummyEps")
+!CHECK: %[[PRIV_PF_ADDR:.*]] = fir.alloca !fir.boxproc<() -> ()> {{.*}}uniq_name = "_QFFtest_sections_dummyEpf"
+!CHECK: %[[PRIV_PF:.*]]:2 = hlfir.declare %[[PRIV_PF_ADDR]] {{.*}}uniq_name("_QFFtest_sections_dummyEpf")
+!CHECK: %[[PF_VAL:.*]] = fir.load %[[PF]]#0 : !fir.ref<!fir.boxproc<() -> ()>>
+!CHECK: fir.store %[[PF_VAL]] to %[[PRIV_PF]]#0 : !fir.ref<!fir.boxproc<() -> ()>>
+!CHECK: %[[PRIV_PS_ADDR:.*]] = fir.alloca !fir.boxproc<() -> ()> {{.*}}uniq_name = "_QFFtest_sections_dummyEps"
+!CHECK: %[[PRIV_PS:.*]]:2 = hlfir.declare %[[PRIV_PS_ADDR]] {{.*}}uniq_name("_QFFtest_sections_dummyEps")
+!CHECK: %[[PS_VAL:.*]] = fir.load %[[PS]]#0 : !fir.ref<!fir.boxproc<() -> ()>>
+!CHECK: fir.store %[[PS_VAL]] to %[[PRIV_PS]]#0 : !fir.ref<!fir.boxproc<() -> ()>>
+!CHECK: omp.sections
+!CHECK: %[[PF_VAL:.*]] = fir.load %[[PRIV_PF]]#0 : !fir.ref<!fir.boxproc<() -> ()>>
+!CHECK: fir.store %[[PF_VAL]] to %[[PF]]#0 : !fir.ref<!fir.boxproc<() -> ()>>
+!CHECK: %[[PS_VAL:.*]] = fir.load %[[PRIV_PS]]#0 : !fir.ref<!fir.boxproc<() -> ()>>
+!CHECK: fir.store %[[PS_VAL]] to %[[PS]]#0 : !fir.ref<!fir.boxproc<() -> ()>>
+subroutine test_sections_dummy(pf, ps)
+ procedure(f), pointer :: pf
+ procedure(sub), pointer :: ps
+
+ !$omp sections firstprivate(pf, ps) lastprivate(pf, ps)
+ pf => f
+ ps => sub
+ !$omp end sections
+end subroutine
+
integer function f(arg)
integer :: arg
f = arg
``````````
</details>
https://github.com/llvm/llvm-project/pull/232752
More information about the flang-commits
mailing list