diff --git a/flang/include/flang/Optimizer/Builder/FIRBuilder.h b/flang/include/flang/Optimizer/Builder/FIRBuilder.h --- a/flang/include/flang/Optimizer/Builder/FIRBuilder.h +++ b/flang/include/flang/Optimizer/Builder/FIRBuilder.h @@ -310,7 +310,8 @@ /// a memory reference type. /// Array entities are boxed with a shape and possibly a shift. Character /// entities are boxed with a LEN parameter. - mlir::Value createBox(mlir::Location loc, const fir::ExtendedValue &exv); + mlir::Value createBox(mlir::Location loc, const fir::ExtendedValue &exv, + bool isPolymorphic = false); /// Create constant i1 with value 1. if \p b is true or 0. otherwise mlir::Value createBool(mlir::Location loc, bool b) { 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 @@ -3410,8 +3410,10 @@ // actually a variable. mlir::Value box = Fortran::evaluate::IsVariable(*expr) - ? builder.createBox(loc, genBoxArg(*expr)) - : builder.createBox(getLoc(), genTempExtAddr(*expr)); + ? builder.createBox(loc, genBoxArg(*expr), + fir::isPolymorphicType(argTy)) + : builder.createBox(getLoc(), genTempExtAddr(*expr), + fir::isPolymorphicType(argTy)); caller.placeInput(arg, box); } } else if (arg.passBy == PassBy::AddressAndLength) { 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 @@ -463,7 +463,8 @@ } mlir::Value fir::FirOpBuilder::createBox(mlir::Location loc, - const fir::ExtendedValue &exv) { + const fir::ExtendedValue &exv, + bool isPolymorphic) { mlir::Value itemAddr = fir::getBase(exv); if (itemAddr.getType().isa()) return itemAddr; @@ -474,6 +475,8 @@ llvm_unreachable("not a memory reference type"); } mlir::Type boxTy = fir::BoxType::get(elementType); + if (isPolymorphic) + boxTy = fir::ClassType::get(elementType); return exv.match( [&](const fir::ArrayBoxValue &box) -> mlir::Value { mlir::Value s = createShape(loc, exv); diff --git a/flang/test/Lower/polymorphic.f90 b/flang/test/Lower/polymorphic.f90 --- a/flang/test/Lower/polymorphic.f90 +++ b/flang/test/Lower/polymorphic.f90 @@ -33,7 +33,7 @@ class(p1) :: this end subroutine - ! Test passing fir.convert accept fir.box
-> fir.class
+ ! Test embox of fir.type to fir.class to be passed-object. subroutine check() type(p1) :: t1 type(p2) :: t2 @@ -44,10 +44,9 @@ ! CHECK-LABEL: func.func @_QMpolymorphic_testPcheck() ! CHECK: %[[DT1:.*]] = fir.alloca !fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}> {bindc_name = "t1", uniq_name = "_QMpolymorphic_testFcheckEt1"} ! CHECK: %[[DT2:.*]] = fir.alloca !fir.type<_QMpolymorphic_testTp2{a:i32,b:i32,c:f32}> {bindc_name = "t2", uniq_name = "_QMpolymorphic_testFcheckEt2"} -! CHECK: %[[BOX1:.*]] = fir.embox %[[DT1]] : (!fir.ref>) -> !fir.box> -! CHECK: %[[CLASS1:.*]] = fir.convert %[[BOX1]] : (!fir.box>) -> !fir.class> +! CHECK: %[[CLASS1:.*]] = fir.embox %[[DT1]] : (!fir.ref>) -> !fir.class> ! CHECK: fir.call @_QMpolymorphic_testPprint(%[[CLASS1]]) : (!fir.class>) -> () -! CHECK: %[[BOX2:.*]] = fir.embox %[[DT2]] : (!fir.ref>) -> !fir.box> -! CHECK: %[[CLASS2:.*]] = fir.convert %[[BOX2]] : (!fir.box>) -> !fir.class> +! CHECK: %[[BOX2:.*]] = fir.embox %[[DT2]] : (!fir.ref>) -> !fir.class> +! CHECK: %[[CLASS2:.*]] = fir.rebox %[[BOX2]] : (!fir.class>) -> !fir.class> ! CHECK: fir.call @_QMpolymorphic_testPprint(%[[CLASS2]]) : (!fir.class>) -> () end module