diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -951,6 +951,7 @@ // Lower TRANSPOSE as a runtime call under -O0. loweringOpts.setOptimizeTranspose(codegenOpts.OptimizationLevel > 0); + loweringOpts.setPolymorphicTypeImpl(true); const LangOptions &langOptions = getLangOpts(); Fortran::common::MathOptionsBase &mathOpts = loweringOpts.getMathOptions(); 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 @@ -2189,6 +2189,19 @@ builder.create(loc, value, temp); return temp; }, + [&](const fir::PolymorphicValue &p) -> ExtValue { + mlir::Type type = p.getAddr().getType(); + mlir::Value value = p.getAddr(); + if (fir::isa_ref_type(type)) + value = builder.create(loc, value); + mlir::Value temp = builder.createTemporary(loc, value.getType()); + builder.create(loc, value, temp); + mlir::Value empty; + mlir::ValueRange emptyRange; + auto boxTy = fir::ClassType::get(value.getType()); + return builder.create(loc, boxTy, temp, empty, empty, + emptyRange, p.getTdesc()); + }, [&](const auto &) -> ExtValue { fir::emitFatalError(loc, "expr is not a scalar value"); }); 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 @@ -182,4 +182,31 @@ ! CHECK: %[[REBOX:.*]] = fir.rebox %[[CLASS]] : (!fir.class>>>) -> !fir.box>> ! CHECK: fir.call @_QMpolymorphic_testPsub_with_type_array(%[[REBOX]]) {{.*}} : (!fir.box>>) -> () + subroutine takes_p1(p) + class(p1), intent(in) :: p + end subroutine + +! CHECK-LABEL: func.func @_QMpolymorphic_testPtakes_p1 + + subroutine no_reassoc_poly_value(a, i) + class(p1), intent(in) :: a(:) + integer :: i + call takes_p1((a(i))) + end subroutine + +! CHECK-LABEL: func.func @_QMpolymorphic_testPno_reassoc_poly_value( +! CHECK-SAME: %[[ARG0:.*]]: !fir.class>> {fir.bindc_name = "a"}, %[[I:.*]]: !fir.ref {fir.bindc_name = "i"}) { +! CHECK: %[[TEMP:.*]] = fir.alloca !fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}> +! CHECK: %[[LOADED_I:.*]] = fir.load %[[I]] : !fir.ref +! CHECK: %[[I_I64:.*]] = fir.convert %[[LOADED_I]] : (i32) -> i64 +! CHECK: %[[C1:.*]] = arith.constant 1 : i64 +! CHECK: %[[IDX:.*]] = arith.subi %[[I_I64]], %[[C1]] : i64 +! CHECK: %[[COORD:.*]] = fir.coordinate_of %[[ARG0]], %[[IDX]] : (!fir.class>>, i64) -> !fir.ref> +! CHECK: %[[TDESC:.*]] = fir.box_tdesc %[[ARG0]] : (!fir.class>>) -> !fir.tdesc +! CHECK: %[[NO_REASSOC:.*]] = fir.no_reassoc %[[COORD]] : !fir.ref> +! CHECK: %[[LOAD:.*]] = fir.load %[[NO_REASSOC]] : !fir.ref> +! CHECK: fir.store %[[LOAD]] to %[[TEMP]] : !fir.ref> +! CHECK: %[[EMBOX:.*]] = fir.embox %[[TEMP]] tdesc %[[TDESC]] : (!fir.ref>, !fir.tdesc) -> !fir.class> +! CHECK: fir.call @_QMpolymorphic_testPtakes_p1(%[[EMBOX]]) {{.*}} : (!fir.class>) -> () + end module