Skip to content

Commit 008b7f1

Browse files
authored
[flang] implement capture of procedure pointers in internal procedures (#89619)
1 parent 9375962 commit 008b7f1

File tree

3 files changed

+32
-4
lines changed

3 files changed

+32
-4
lines changed

flang/lib/Lower/ConvertVariable.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1715,7 +1715,8 @@ void Fortran::lower::genDeclareSymbol(
17151715
const fir::ExtendedValue &exv, fir::FortranVariableFlagsEnum extraFlags,
17161716
bool force) {
17171717
if (converter.getLoweringOptions().getLowerToHighLevelFIR() &&
1718-
!Fortran::semantics::IsProcedure(sym) &&
1718+
(!Fortran::semantics::IsProcedure(sym) ||
1719+
Fortran::semantics::IsPointer(sym)) &&
17191720
!sym.detailsIf<Fortran::semantics::CommonBlockDetails>()) {
17201721
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
17211722
const mlir::Location loc = genLocation(converter, sym);

flang/lib/Lower/HostAssociations.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,10 +182,10 @@ class CapturedProcedure : public CapturedSymbols<CapturedProcedure> {
182182
public:
183183
static mlir::Type getType(Fortran::lower::AbstractConverter &converter,
184184
const Fortran::semantics::Symbol &sym) {
185+
mlir::Type funTy = Fortran::lower::getDummyProcedureType(sym, converter);
185186
if (Fortran::semantics::IsPointer(sym))
186-
TODO(converter.getCurrentLocation(),
187-
"capture procedure pointer in internal procedure");
188-
return Fortran::lower::getDummyProcedureType(sym, converter);
187+
return fir::ReferenceType::get(funTy);
188+
return funTy;
189189
}
190190

191191
static void instantiateHostTuple(const InstantiateHostTuple &args,

flang/test/Lower/HLFIR/internal-procedures.f90

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,30 @@ subroutine internal()
5252
! CHECK: %[[VAL_4:.*]]:2 = fir.unboxchar %[[VAL_3]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
5353
! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_4]]#0 typeparams %[[VAL_4]]#1 {fortran_attrs = #fir.var_attrs<host_assoc>, uniq_name = "_QFtest_scalar_charEc"} : (!fir.ref<!fir.char<1,?>>, index) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>)
5454
! CHECK: fir.call @_QPbar(%[[VAL_5]]#0) {{.*}}: (!fir.boxchar<1>) -> ()
55+
56+
subroutine test_proc_pointer(p)
57+
real, pointer, external :: p
58+
call internal()
59+
contains
60+
subroutine internal()
61+
real :: x
62+
x = p()
63+
end subroutine
64+
end subroutine
65+
! CHECK-LABEL: func.func @_QPtest_proc_pointer(
66+
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.boxproc<() -> ()>>) {
67+
! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtest_proc_pointerEp"} : (!fir.ref<!fir.boxproc<() -> ()>>) -> (!fir.ref<!fir.boxproc<() -> ()>>, !fir.ref<!fir.boxproc<() -> ()>>)
68+
! CHECK: %[[VAL_2:.*]] = fir.alloca tuple<!fir.ref<!fir.boxproc<() -> ()>>>
69+
! CHECK: %[[VAL_3:.*]] = arith.constant 0 : i32
70+
! CHECK: %[[VAL_4:.*]] = fir.coordinate_of %[[VAL_2]], %[[VAL_3]] : (!fir.ref<tuple<!fir.ref<!fir.boxproc<() -> ()>>>>, i32) -> !fir.llvm_ptr<!fir.ref<!fir.boxproc<() -> ()>>>
71+
! CHECK: fir.store %[[VAL_1]]#1 to %[[VAL_4]] : !fir.llvm_ptr<!fir.ref<!fir.boxproc<() -> ()>>>
72+
! CHECK: fir.call @_QFtest_proc_pointerPinternal(%[[VAL_2]]) {{.*}}: (!fir.ref<tuple<!fir.ref<!fir.boxproc<() -> ()>>>>) -> ()
73+
! CHECK: return
74+
! CHECK: }
75+
76+
! CHECK-LABEL: func.func private @_QFtest_proc_pointerPinternal(
77+
! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<tuple<!fir.ref<!fir.boxproc<() -> ()>>>> {fir.host_assoc}) attributes {fir.host_symbol = @_QPtest_proc_pointer, llvm.linkage = #llvm.linkage<internal>} {
78+
! CHECK: %[[VAL_1:.*]] = arith.constant 0 : i32
79+
! CHECK: %[[VAL_2:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_1]] : (!fir.ref<tuple<!fir.ref<!fir.boxproc<() -> ()>>>>, i32) -> !fir.llvm_ptr<!fir.ref<!fir.boxproc<() -> ()>>>
80+
! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_2]] : !fir.llvm_ptr<!fir.ref<!fir.boxproc<() -> ()>>>
81+
! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_3]] {fortran_attrs = #fir.var_attrs<pointer, host_assoc>, uniq_name = "_QFtest_proc_pointerEp"} : (!fir.ref<!fir.boxproc<() -> ()>>) -> (!fir.ref<!fir.boxproc<() -> ()>>, !fir.ref<!fir.boxproc<() -> ()>>)

0 commit comments

Comments
 (0)