diff --git a/flang/lib/Lower/ConvertExprToHLFIR.cpp b/flang/lib/Lower/ConvertExprToHLFIR.cpp index 698f3422bda6f..e45c822ee3bf5 100644 --- a/flang/lib/Lower/ConvertExprToHLFIR.cpp +++ b/flang/lib/Lower/ConvertExprToHLFIR.cpp @@ -1525,11 +1525,6 @@ class HlfirBuilder { // Elemental expression. mlir::Type elementType; if constexpr (R::category == Fortran::common::TypeCategory::Derived) { - // TODO: need to pass a mold to hlfir.elemental for polymorphic arrays - // if using hlfir.elemental here so that it can get the dynamic type - // info. - if (left.isPolymorphic()) - TODO(loc, "parenthesized polymorphic arrays in HLFIR"); elementType = Fortran::lower::translateDerivedTypeToFIRType( getConverter(), op.derived().GetType().GetDerivedTypeSpec()); } else { @@ -1545,9 +1540,9 @@ class HlfirBuilder { auto leftVal = hlfir::loadTrivialScalar(l, b, leftElement); return unaryOp.gen(l, b, op.derived(), leftVal); }; - mlir::Value elemental = hlfir::genElementalOp(loc, builder, elementType, - shape, typeParams, genKernel, - /*isUnordered=*/true); + mlir::Value elemental = hlfir::genElementalOp( + loc, builder, elementType, shape, typeParams, genKernel, + /*isUnordered=*/true, left.isPolymorphic() ? left : mlir::Value{}); fir::FirOpBuilder *bldr = &builder; getStmtCtx().attachCleanup( [=]() { bldr->create(loc, elemental); }); diff --git a/flang/test/Lower/HLFIR/elemental-array-ops.f90 b/flang/test/Lower/HLFIR/elemental-array-ops.f90 index 2a6abfc78ac18..8fa6b08b083ca 100644 --- a/flang/test/Lower/HLFIR/elemental-array-ops.f90 +++ b/flang/test/Lower/HLFIR/elemental-array-ops.f90 @@ -1,5 +1,5 @@ ! Test lowering of elemental intrinsic operations with array arguments to HLFIR -! RUN: bbc -emit-hlfir -o - %s 2>&1 | FileCheck %s +! RUN: bbc -emit-hlfir --polymorphic-type -I nowhere -o - %s 2>&1 | FileCheck %s subroutine binary(x, y) integer :: x(100), y(100) @@ -212,3 +212,29 @@ end subroutine char_return ! CHECK: hlfir.destroy %[[VAL_47:.*]] : !hlfir.expr> ! CHECK: return ! CHECK: } + +subroutine polymorphic_parenthesis(x, y) + type t + end type t + class(t), allocatable :: x(:) + class(t), intent(in) :: y(:) + x = (y) +end subroutine polymorphic_parenthesis +! CHECK-LABEL: func.func @_QPpolymorphic_parenthesis( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>>> {fir.bindc_name = "x"}, +! CHECK-SAME: %[[VAL_1:.*]]: !fir.class>> {fir.bindc_name = "y"}) { +! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QFpolymorphic_parenthesisEx"} : (!fir.ref>>>>) -> (!fir.ref>>>>, !fir.ref>>>>) +! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_1]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QFpolymorphic_parenthesisEy"} : (!fir.class>>) -> (!fir.class>>, !fir.class>>) +! CHECK: %[[VAL_4:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_3]]#0, %[[VAL_4]] : (!fir.class>>, index) -> (index, index, index) +! CHECK: %[[VAL_6:.*]] = fir.shape %[[VAL_5]]#1 : (index) -> !fir.shape<1> +! CHECK: %[[VAL_7:.*]] = hlfir.elemental %[[VAL_6]] mold %[[VAL_3]]#0 unordered : (!fir.shape<1>, !fir.class>>) -> !hlfir.expr?> { +! CHECK: ^bb0(%[[VAL_8:.*]]: index): +! CHECK: %[[VAL_9:.*]] = hlfir.designate %[[VAL_3]]#0 (%[[VAL_8]]) : (!fir.class>>, index) -> !fir.class> +! CHECK: %[[VAL_10:.*]] = hlfir.as_expr %[[VAL_9]] : (!fir.class>) -> !hlfir.expr?> +! CHECK: hlfir.yield_element %[[VAL_10]] : !hlfir.expr?> +! CHECK: } +! CHECK: hlfir.assign %[[VAL_7]] to %[[VAL_2]]#0 realloc : !hlfir.expr?>, !fir.ref>>>> +! CHECK: hlfir.destroy %[[VAL_7]] : !hlfir.expr?> +! CHECK: return +! CHECK: }