@@ -1227,26 +1227,32 @@ static PreparedDummyArgument preparePresentUserCallActualArgument(
12271227 return hlfir::Entity{copyIn.getCopiedIn ()};
12281228 };
12291229
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+
12301246 // Step 2: prepare the storage for the dummy arguments, ensuring that it
12311247 // matches the dummy requirements (e.g., must be contiguous or must be
12321248 // a temporary).
12331249 hlfir::Entity entity =
12341250 hlfir::derefPointersAndAllocatables (loc, builder, actual);
12351251 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);
12501256 if (arg.hasValueAttribute () ||
12511257 // Constant expressions might be lowered as variables with
12521258 // 'parameter' attribute. Even though the constant expressions
@@ -1285,20 +1291,14 @@ static PreparedDummyArgument preparePresentUserCallActualArgument(
12851291 loc, builder, entity, storageType, " " , byRefAttr);
12861292 entity = hlfir::Entity{associate.getBase ()};
12871293 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.
12881300 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);
13021302 entity = genCopyIn (entity, /* doCopyOut=*/ false );
13031303 }
13041304 }
0 commit comments