@@ -1227,26 +1227,32 @@ static PreparedDummyArgument preparePresentUserCallActualArgument(
1227
1227
return hlfir::Entity{copyIn.getCopiedIn ()};
1228
1228
};
1229
1229
1230
+ auto genSetDynamicTypeToDummyType = [&](hlfir::Entity var) -> hlfir::Entity {
1231
+ fir::BaseBoxType boxType = fir::BoxType::get (
1232
+ hlfir::getFortranElementOrSequenceType (dummyTypeWithActualRank));
1233
+ if (actualIsAssumedRank)
1234
+ return hlfir::Entity{builder.create <fir::ReboxAssumedRankOp>(
1235
+ loc, boxType, var, fir::LowerBoundModifierAttribute::SetToOnes)};
1236
+ // Use actual shape when creating descriptor with dummy type, the dummy
1237
+ // shape may be unknown in case of sequence association.
1238
+ mlir::Type actualTy =
1239
+ hlfir::getFortranElementOrSequenceType (actual.getType ());
1240
+ boxType = boxType.getBoxTypeWithNewShape (actualTy);
1241
+ return hlfir::Entity{builder.create <fir::ReboxOp>(loc, boxType, var,
1242
+ /* shape=*/ mlir::Value{},
1243
+ /* slice=*/ mlir::Value{})};
1244
+ };
1245
+
1230
1246
// Step 2: prepare the storage for the dummy arguments, ensuring that it
1231
1247
// matches the dummy requirements (e.g., must be contiguous or must be
1232
1248
// a temporary).
1233
1249
hlfir::Entity entity =
1234
1250
hlfir::derefPointersAndAllocatables (loc, builder, actual);
1235
1251
if (entity.isVariable ()) {
1236
- if (mustSetDynamicTypeToDummyType) {
1237
- // Note: this is important to do this before any copy-in or copy so
1238
- // that the dummy is contiguous according to the dummy type.
1239
- mlir::Type boxType = fir::BoxType::get (
1240
- hlfir::getFortranElementOrSequenceType (dummyTypeWithActualRank));
1241
- if (actualIsAssumedRank) {
1242
- entity = hlfir::Entity{builder.create <fir::ReboxAssumedRankOp>(
1243
- loc, boxType, entity, fir::LowerBoundModifierAttribute::SetToOnes)};
1244
- } else {
1245
- entity = hlfir::Entity{builder.create <fir::ReboxOp>(
1246
- loc, boxType, entity, /* shape=*/ mlir::Value{},
1247
- /* slice=*/ mlir::Value{})};
1248
- }
1249
- }
1252
+ // Set dynamic type if needed before any copy-in or copy so that the dummy
1253
+ // is contiguous according to the dummy type.
1254
+ if (mustSetDynamicTypeToDummyType)
1255
+ entity = genSetDynamicTypeToDummyType (entity);
1250
1256
if (arg.hasValueAttribute () ||
1251
1257
// Constant expressions might be lowered as variables with
1252
1258
// 'parameter' attribute. Even though the constant expressions
@@ -1285,20 +1291,14 @@ static PreparedDummyArgument preparePresentUserCallActualArgument(
1285
1291
loc, builder, entity, storageType, " " , byRefAttr);
1286
1292
entity = hlfir::Entity{associate.getBase ()};
1287
1293
preparedDummy.pushExprAssociateCleanUp (associate);
1294
+ // Rebox the actual argument to the dummy argument's type, and make sure
1295
+ // that we pass a contiguous entity (i.e. make copy-in, if needed).
1296
+ //
1297
+ // TODO: this can probably be optimized by associating the expression with
1298
+ // properly typed temporary, but this needs either a new operation or
1299
+ // making the hlfir.associate more complex.
1288
1300
if (mustSetDynamicTypeToDummyType) {
1289
- // Rebox the actual argument to the dummy argument's type, and make
1290
- // sure that we pass a contiguous entity (i.e. make copy-in,
1291
- // if needed).
1292
- //
1293
- // TODO: this can probably be optimized by associating the expression
1294
- // with properly typed temporary, but this needs either a new operation
1295
- // or making the hlfir.associate more complex.
1296
- assert (!actualIsAssumedRank && " only variables are assumed-rank" );
1297
- mlir::Type boxType = fir::BoxType::get (
1298
- hlfir::getFortranElementOrSequenceType (dummyTypeWithActualRank));
1299
- entity = hlfir::Entity{builder.create <fir::ReboxOp>(
1300
- loc, boxType, entity, /* shape=*/ mlir::Value{},
1301
- /* slice=*/ mlir::Value{})};
1301
+ entity = genSetDynamicTypeToDummyType (entity);
1302
1302
entity = genCopyIn (entity, /* doCopyOut=*/ false );
1303
1303
}
1304
1304
}
0 commit comments