diff --git a/flang/include/flang/Optimizer/Dialect/FIRType.h b/flang/include/flang/Optimizer/Dialect/FIRType.h --- a/flang/include/flang/Optimizer/Dialect/FIRType.h +++ b/flang/include/flang/Optimizer/Dialect/FIRType.h @@ -318,6 +318,9 @@ /// value. bool isUnlimitedPolymorphicType(mlir::Type ty); +/// Return true iff `ty` is the type of an assumed type. +bool isAssumedType(mlir::Type ty); + /// Return true iff `boxTy` wraps a record type or an unlimited polymorphic /// entity. Polymorphic entities with intrinsic type spec do not have addendum inline bool boxHasAddendum(fir::BaseBoxType boxTy) { diff --git a/flang/lib/Lower/ConvertExpr.cpp b/flang/lib/Lower/ConvertExpr.cpp --- a/flang/lib/Lower/ConvertExpr.cpp +++ b/flang/lib/Lower/ConvertExpr.cpp @@ -2715,12 +2715,12 @@ box = Fortran::evaluate::IsVariable(*expr) ? builder.createBox(loc, genBoxArg(*expr), fir::isPolymorphicType(argTy), - fir::isBoxNone(argTy)) + fir::isAssumedType(argTy)) : builder.createBox(getLoc(), genTempExtAddr(*expr), fir::isPolymorphicType(argTy), - fir::isBoxNone(argTy)); + fir::isAssumedType(argTy)); if (box.getType().isa() && - fir::isPolymorphicType(argTy) && !fir::isBoxNone(argTy)) { + fir::isPolymorphicType(argTy) && !fir::isAssumedType(argTy)) { mlir::Type actualTy = argTy; if (Fortran::lower::isParentComponent(*expr)) actualTy = fir::BoxType::get(converter.genType(*expr)); diff --git a/flang/lib/Optimizer/Builder/FIRBuilder.cpp b/flang/lib/Optimizer/Builder/FIRBuilder.cpp --- a/flang/lib/Optimizer/Builder/FIRBuilder.cpp +++ b/flang/lib/Optimizer/Builder/FIRBuilder.cpp @@ -360,10 +360,11 @@ return create(loc, toTy, proc); } - if ((fir::isPolymorphicType(fromTy) && - (fir::isAllocatableType(fromTy) || fir::isPointerType(fromTy)) && - fir::isPolymorphicType(toTy)) || - (fir::isPolymorphicType(fromTy) && toTy.isa())) + if (((fir::isPolymorphicType(fromTy) && + (fir::isAllocatableType(fromTy) || fir::isPointerType(fromTy)) && + fir::isPolymorphicType(toTy)) || + (fir::isPolymorphicType(fromTy) && toTy.isa())) && + !(fir::isUnlimitedPolymorphicType(fromTy) && fir::isAssumedType(toTy))) return create(loc, toTy, val, mlir::Value{}, /*slice=*/mlir::Value{}); diff --git a/flang/lib/Optimizer/Dialect/FIRType.cpp b/flang/lib/Optimizer/Dialect/FIRType.cpp --- a/flang/lib/Optimizer/Dialect/FIRType.cpp +++ b/flang/lib/Optimizer/Dialect/FIRType.cpp @@ -300,7 +300,7 @@ return false; } -static bool isAssumedType(mlir::Type ty) { +bool isAssumedType(mlir::Type ty) { if (auto boxTy = ty.dyn_cast()) { if (boxTy.getEleTy().isa()) return true; diff --git a/flang/test/Lower/assumed-type.f90 b/flang/test/Lower/assumed-type.f90 --- a/flang/test/Lower/assumed-type.f90 +++ b/flang/test/Lower/assumed-type.f90 @@ -8,6 +8,12 @@ end subroutine end interface + interface + subroutine assumed_r(a) + type(*), intent(in), target :: a(*) + end subroutine + end interface + contains subroutine call_assmued() @@ -20,4 +26,17 @@ ! CHECK: %[[BOX_NONE:.*]] = fir.embox %[[I]] : (!fir.ref) -> !fir.box ! CHECK: fir.call @_QPassumed(%[[BOX_NONE]]) fastmath : (!fir.box) -> () + subroutine call_assumed_r() + integer, target :: i(10) + call assumed_r(i) + end subroutine + +! CHECK-LABEL: func.func @_QMassumed_type_testPcall_assumed_r() { +! CHECK: %[[C10:.*]] = arith.constant 10 : index +! CHECK: %[[I:.*]] = fir.alloca !fir.array<10xi32> {bindc_name = "i", fir.target, uniq_name = "_QMassumed_type_testFcall_assumed_rEi"} +! CHECK: %[[SHAPE:.*]] = fir.shape %[[C10]] : (index) -> !fir.shape<1> +! CHECK: %[[BOX_NONE:.*]] = fir.embox %[[I]](%[[SHAPE]]) : (!fir.ref>, !fir.shape<1>) -> !fir.box> +! CHECK: %[[CONV:.*]] = fir.convert %[[BOX_NONE]] : (!fir.box>) -> !fir.box> +! CHECK: fir.call @_QPassumed_r(%[[CONV]]) {{.*}} : (!fir.box>) -> () + end module