[flang-commits] [flang] 3dc314b - [flang] Fix lowering of unused dummy procedure pointers (#155649)
via flang-commits
flang-commits at lists.llvm.org
Mon Sep 8 04:39:11 PDT 2025
Author: Leandro Lupori
Date: 2025-09-08T08:39:07-03:00
New Revision: 3dc314b8519099b1da43d01302d3d1710a6ccb3c
URL: https://github.com/llvm/llvm-project/commit/3dc314b8519099b1da43d01302d3d1710a6ccb3c
DIFF: https://github.com/llvm/llvm-project/commit/3dc314b8519099b1da43d01302d3d1710a6ccb3c.diff
LOG: [flang] Fix lowering of unused dummy procedure pointers (#155649)
Fixes #126453
Added:
flang/test/Lower/HLFIR/dummy-proc-ptr-in-entry.f90
Modified:
flang/include/flang/Lower/CallInterface.h
flang/lib/Lower/CallInterface.cpp
flang/lib/Lower/ConvertVariable.cpp
Removed:
################################################################################
diff --git a/flang/include/flang/Lower/CallInterface.h b/flang/include/flang/Lower/CallInterface.h
index 72bc9dd890a94..926a42756c6ef 100644
--- a/flang/include/flang/Lower/CallInterface.h
+++ b/flang/include/flang/Lower/CallInterface.h
@@ -478,6 +478,12 @@ getOrDeclareFunction(const Fortran::evaluate::ProcedureDesignator &,
mlir::Type getDummyProcedureType(const Fortran::semantics::Symbol &dummyProc,
Fortran::lower::AbstractConverter &);
+/// Return the type of an argument that is a dummy procedure pointer. This
+/// will be a reference to a boxed procedure.
+mlir::Type
+getDummyProcedurePointerType(const Fortran::semantics::Symbol &dummyProcPtr,
+ Fortran::lower::AbstractConverter &);
+
/// Return !fir.boxproc<() -> ()> type.
mlir::Type getUntypedBoxProcType(mlir::MLIRContext *context);
diff --git a/flang/lib/Lower/CallInterface.cpp b/flang/lib/Lower/CallInterface.cpp
index 72431a9cfacc4..c3284cd936f8f 100644
--- a/flang/lib/Lower/CallInterface.cpp
+++ b/flang/lib/Lower/CallInterface.cpp
@@ -1766,6 +1766,17 @@ mlir::Type Fortran::lower::getDummyProcedureType(
return procType;
}
+mlir::Type Fortran::lower::getDummyProcedurePointerType(
+ const Fortran::semantics::Symbol &dummyProcPtr,
+ Fortran::lower::AbstractConverter &converter) {
+ std::optional<Fortran::evaluate::characteristics::Procedure> iface =
+ Fortran::evaluate::characteristics::Procedure::Characterize(
+ dummyProcPtr, converter.getFoldingContext());
+ mlir::Type procPtrType = getProcedureDesignatorType(
+ iface.has_value() ? &*iface : nullptr, converter);
+ return fir::ReferenceType::get(procPtrType);
+}
+
bool Fortran::lower::isCPtrArgByValueType(mlir::Type ty) {
return mlir::isa<fir::ReferenceType>(ty) &&
fir::isa_integer(fir::unwrapRefType(ty));
diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
index 88fc3128d21f7..c79c9b1ab0f51 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -2159,15 +2159,19 @@ void Fortran::lower::mapSymbolAttributes(
if (Fortran::semantics::IsProcedure(sym)) {
if (isUnusedEntryDummy) {
// Additional discussion below.
- mlir::Type dummyProcType =
- Fortran::lower::getDummyProcedureType(sym, converter);
- mlir::Value undefOp = fir::UndefOp::create(builder, loc, dummyProcType);
-
- Fortran::lower::genDeclareSymbol(converter, symMap, sym, undefOp);
- }
-
- // Procedure pointer.
- if (Fortran::semantics::IsPointer(sym)) {
+ if (Fortran::semantics::IsPointer(sym)) {
+ mlir::Type procPtrType =
+ Fortran::lower::getDummyProcedurePointerType(sym, converter);
+ mlir::Value undefOp = fir::UndefOp::create(builder, loc, procPtrType);
+ genProcPointer(converter, symMap, sym, undefOp, replace);
+ } else {
+ mlir::Type dummyProcType =
+ Fortran::lower::getDummyProcedureType(sym, converter);
+ mlir::Value undefOp = fir::UndefOp::create(builder, loc, dummyProcType);
+ Fortran::lower::genDeclareSymbol(converter, symMap, sym, undefOp);
+ }
+ } else if (Fortran::semantics::IsPointer(sym)) {
+ // Used procedure pointer.
// global
mlir::Value boxAlloc = preAlloc;
// dummy or passed result
diff --git a/flang/test/Lower/HLFIR/dummy-proc-ptr-in-entry.f90 b/flang/test/Lower/HLFIR/dummy-proc-ptr-in-entry.f90
new file mode 100644
index 0000000000000..280268112d5a0
--- /dev/null
+++ b/flang/test/Lower/HLFIR/dummy-proc-ptr-in-entry.f90
@@ -0,0 +1,59 @@
+! Test dummy procedure pointers that are not an argument in every entry.
+! This requires creating a mock value in the entries where it is not an
+! argument.
+!
+!RUN: %flang_fc1 -emit-hlfir %s -o - 2>&1 | FileCheck %s
+
+!CHECK-LABEL: func @_QPdummy_char_proc_ptr() -> !fir.boxproc<(!fir.ref<!fir.char<1>>, index) -> !fir.boxchar<1>> {
+!CHECK: %[[UNDEF:.*]] = fir.undefined !fir.ref<!fir.boxproc<() -> ()>>
+!CHECK: %{{.*}}:2 = hlfir.declare %[[UNDEF]]
+!CHECK-SAME: {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFdummy_char_proc_ptrEdummy"}
+!CHECK-SAME: : (!fir.ref<!fir.boxproc<() -> ()>>)
+!CHECK-SAME: -> (!fir.ref<!fir.boxproc<() -> ()>>, !fir.ref<!fir.boxproc<() -> ()>>)
+
+!CHECK-LABEL: func @_QPdummy_char_proc_ptr_entry(
+!CHECK-SAME: %[[ARG:.*]]: !fir.ref<!fir.boxproc<() -> ()>>)
+!CHECK-SAME: -> !fir.boxproc<(!fir.ref<!fir.char<1>>, index) -> !fir.boxchar<1>> {
+!CHECK: %{{.*}}:2 = hlfir.declare %[[ARG]] dummy_scope %{{[^ ]*}}
+!CHECK-SAME: {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFdummy_char_proc_ptrEdummy"}
+!CHECK-SAME: : (!fir.ref<!fir.boxproc<() -> ()>>, !fir.dscope)
+!CHECK-SAME: -> (!fir.ref<!fir.boxproc<() -> ()>>, !fir.ref<!fir.boxproc<() -> ()>>)
+function dummy_char_proc_ptr() result(fun)
+ interface
+ character function char_fun()
+ end function
+ end interface
+
+ procedure (char_fun), pointer :: fun, dummy_char_proc_ptr_entry, dummy
+ fun => null()
+ return
+
+ entry dummy_char_proc_ptr_entry(dummy)
+end function
+
+!CHECK-LABEL: func @_QPdummy_int_proc_ptr()
+!CHECK: %[[UNDEF:.*]] = fir.undefined !fir.ref<!fir.boxproc<() -> ()>>
+!CHECK: %{{.*}}:2 = hlfir.declare %[[UNDEF]]
+!CHECK-SAME: {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFdummy_int_proc_ptrEdummy"}
+!CHECK-SAME: : (!fir.ref<!fir.boxproc<() -> ()>>)
+!CHECK-SAME: -> (!fir.ref<!fir.boxproc<() -> ()>>, !fir.ref<!fir.boxproc<() -> ()>>)
+
+!CHECK-LABEL: func @_QPdummy_int_proc_ptr_entry(
+!CHECK-SAME: %[[ARG:.*]]: !fir.ref<!fir.boxproc<() -> ()>>)
+!CHECK-SAME: -> !fir.boxproc<() -> i32> {
+!CHECK: %{{.*}}:2 = hlfir.declare %[[ARG]] dummy_scope %{{[^ ]*}}
+!CHECK-SAME: {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFdummy_int_proc_ptrEdummy"}
+!CHECK-SAME: : (!fir.ref<!fir.boxproc<() -> ()>>, !fir.dscope)
+!CHECK-SAME: -> (!fir.ref<!fir.boxproc<() -> ()>>, !fir.ref<!fir.boxproc<() -> ()>>)
+function dummy_int_proc_ptr() result(fun)
+ interface
+ integer function int_fun()
+ end function
+ end interface
+
+ procedure (int_fun), pointer :: fun, dummy_int_proc_ptr_entry, dummy
+ fun => null()
+ return
+
+ entry dummy_int_proc_ptr_entry(dummy)
+end function
More information about the flang-commits
mailing list