@@ -912,37 +912,16 @@ static PreparedDummyArgument preparePresentUserCallActualArgument(
912
912
// element if this is an array in an elemental call.
913
913
hlfir::Entity actual = preparedActual.getActual (loc, builder);
914
914
915
- // Handle the procedure pointer actual arguments.
916
- if (actual.isProcedurePointer ()) {
917
- // Procedure pointer actual to procedure pointer dummy.
918
- if (fir::isBoxProcAddressType (dummyType))
919
- return PreparedDummyArgument{actual, /* cleanups=*/ {}};
915
+ // Handle procedure arguments (procedure pointers should go through
916
+ // prepareProcedurePointerActualArgument).
917
+ if (hlfir::isFortranProcedureValue (dummyType)) {
920
918
// Procedure pointer actual to procedure dummy.
921
- if (hlfir::isFortranProcedureValue (dummyType )) {
919
+ if (actual. isProcedurePointer ( )) {
922
920
actual = hlfir::derefPointersAndAllocatables (loc, builder, actual);
923
921
return PreparedDummyArgument{actual, /* cleanups=*/ {}};
924
922
}
925
- }
926
-
927
- // NULL() actual to procedure pointer dummy
928
- if (Fortran::evaluate::IsNullProcedurePointer (expr) &&
929
- fir::isBoxProcAddressType (dummyType)) {
930
- auto boxTy{Fortran::lower::getUntypedBoxProcType (builder.getContext ())};
931
- auto tempBoxProc{builder.createTemporary (loc, boxTy)};
932
- hlfir::Entity nullBoxProc (
933
- fir::factory::createNullBoxProc (builder, loc, boxTy));
934
- builder.create <fir::StoreOp>(loc, nullBoxProc, tempBoxProc);
935
- return PreparedDummyArgument{tempBoxProc, /* cleanups=*/ {}};
936
- }
937
-
938
- if (actual.isProcedure ()) {
939
- // Procedure actual to procedure pointer dummy.
940
- if (fir::isBoxProcAddressType (dummyType)) {
941
- auto tempBoxProc{builder.createTemporary (loc, actual.getType ())};
942
- builder.create <fir::StoreOp>(loc, actual, tempBoxProc);
943
- return PreparedDummyArgument{tempBoxProc, /* cleanups=*/ {}};
944
- }
945
923
// Procedure actual to procedure dummy.
924
+ assert (actual.isProcedure ());
946
925
// Do nothing if this is a procedure argument. It is already a
947
926
// fir.boxproc/fir.tuple<fir.boxproc, len> as it should.
948
927
if (actual.getType () != dummyType)
@@ -1219,6 +1198,34 @@ static PreparedDummyArgument prepareUserCallActualArgument(
1219
1198
return result;
1220
1199
}
1221
1200
1201
+ // / Prepare actual argument for a procedure pointer dummy.
1202
+ static PreparedDummyArgument prepareProcedurePointerActualArgument (
1203
+ mlir::Location loc, fir::FirOpBuilder &builder,
1204
+ const Fortran::lower::PreparedActualArgument &preparedActual,
1205
+ mlir::Type dummyType,
1206
+ const Fortran::lower::CallerInterface::PassedEntity &arg,
1207
+ const Fortran::lower::SomeExpr &expr, CallContext &callContext) {
1208
+
1209
+ // NULL() actual to procedure pointer dummy
1210
+ if (Fortran::evaluate::UnwrapExpr<Fortran::evaluate::NullPointer>(expr) &&
1211
+ fir::isBoxProcAddressType (dummyType)) {
1212
+ auto boxTy{Fortran::lower::getUntypedBoxProcType (builder.getContext ())};
1213
+ auto tempBoxProc{builder.createTemporary (loc, boxTy)};
1214
+ hlfir::Entity nullBoxProc (
1215
+ fir::factory::createNullBoxProc (builder, loc, boxTy));
1216
+ builder.create <fir::StoreOp>(loc, nullBoxProc, tempBoxProc);
1217
+ return PreparedDummyArgument{tempBoxProc, /* cleanups=*/ {}};
1218
+ }
1219
+ hlfir::Entity actual = preparedActual.getActual (loc, builder);
1220
+ if (actual.isProcedurePointer ())
1221
+ return PreparedDummyArgument{actual, /* cleanups=*/ {}};
1222
+ assert (actual.isProcedure ());
1223
+ // Procedure actual to procedure pointer dummy.
1224
+ auto tempBoxProc{builder.createTemporary (loc, actual.getType ())};
1225
+ builder.create <fir::StoreOp>(loc, actual, tempBoxProc);
1226
+ return PreparedDummyArgument{tempBoxProc, /* cleanups=*/ {}};
1227
+ }
1228
+
1222
1229
// / Lower calls to user procedures with actual arguments that have been
1223
1230
// / pre-lowered but not yet prepared according to the interface.
1224
1231
// / This can be called for elemental procedures, but only with scalar
@@ -1284,14 +1291,21 @@ genUserCall(Fortran::lower::PreparedActualArguments &loweredActuals,
1284
1291
case PassBy::CharBoxValueAttribute:
1285
1292
case PassBy::Box:
1286
1293
case PassBy::BaseAddress:
1287
- case PassBy::BoxProcRef:
1288
1294
case PassBy::BoxChar: {
1289
1295
PreparedDummyArgument preparedDummy = prepareUserCallActualArgument (
1290
1296
loc, builder, *preparedActual, argTy, arg, *expr, callContext);
1291
1297
callCleanUps.append (preparedDummy.cleanups .rbegin (),
1292
1298
preparedDummy.cleanups .rend ());
1293
1299
caller.placeInput (arg, preparedDummy.dummy );
1294
1300
} break ;
1301
+ case PassBy::BoxProcRef: {
1302
+ PreparedDummyArgument preparedDummy =
1303
+ prepareProcedurePointerActualArgument (loc, builder, *preparedActual,
1304
+ argTy, arg, *expr, callContext);
1305
+ callCleanUps.append (preparedDummy.cleanups .rbegin (),
1306
+ preparedDummy.cleanups .rend ());
1307
+ caller.placeInput (arg, preparedDummy.dummy );
1308
+ } break ;
1295
1309
case PassBy::AddressAndLength:
1296
1310
// PassBy::AddressAndLength is only used for character results. Results
1297
1311
// are not handled here.
0 commit comments