diff --git a/flang/lib/Lower/ConvertExprToHLFIR.cpp b/flang/lib/Lower/ConvertExprToHLFIR.cpp index 5f8b8ec1cafdb..fda0ca1e35cdd 100644 --- a/flang/lib/Lower/ConvertExprToHLFIR.cpp +++ b/flang/lib/Lower/ConvertExprToHLFIR.cpp @@ -775,11 +775,6 @@ class HlfirDesignatorBuilder { llvm::ArrayRef resultExtents) { fir::FirOpBuilder &builder = getBuilder(); mlir::Value shape = builder.genShape(loc, resultExtents); - // For polymorphic entities, it will be needed to add a mold on the - // hlfir.elemental_addr/hlfir.elemental so that we are able to create - // temporary storage for it. - if (partInfo.base && partInfo.base->isPolymorphic()) - TODO(loc, "vector subscripted polymorphic entity in HLFIR"); // The type parameters to be added on the hlfir.elemental_addr are the ones // of the whole designator (not the ones of the vector subscripted part). // These are not yet known and will be added when finalizing the designator @@ -827,6 +822,15 @@ class HlfirDesignatorBuilder { hlfir::EntityWithAttributes elementAddr) { fir::FirOpBuilder &builder = getBuilder(); builder.setInsertionPointToEnd(&elementalAddrOp.getBody().front()); + // For polymorphic entities, it will be needed to add a mold on the + // hlfir.elemental so that we are able to create temporary storage + // for it using the dynamic type. It seems that a reference to the mold + // entity can be created by evaluating the hlfir.elemental_addr + // for a single index. The evaluation should be legal as long as + // the hlfir.elemental_addr has no side effects, otherwise, + // it is not clear how to get the mold reference. + if (elementAddr.isPolymorphic()) + TODO(loc, "vector subscripted polymorphic entity in HLFIR"); builder.create(loc, elementAddr); builder.setInsertionPointAfter(elementalAddrOp); } diff --git a/flang/test/Lower/HLFIR/designators-component-ref.f90 b/flang/test/Lower/HLFIR/designators-component-ref.f90 index ed0a53e185724..3e9fa037040d5 100644 --- a/flang/test/Lower/HLFIR/designators-component-ref.f90 +++ b/flang/test/Lower/HLFIR/designators-component-ref.f90 @@ -1,5 +1,5 @@ ! Test lowering of component reference to HLFIR -! RUN: bbc -emit-hlfir -o - %s | FileCheck %s +! RUN: bbc -emit-hlfir --polymorphic-type -o - %s | FileCheck %s module comp_ref type t1 integer :: scalar_i @@ -367,3 +367,45 @@ subroutine test_scalar_array_complex_chain(a) ! CHECK: %[[VAL_30:.*]] = fir.shape %[[VAL_23]], %[[VAL_29]] : (index, index) -> !fir.shape<2> ! CHECK: %[[VAL_31:.*]] = hlfir.designate %[[VAL_1]]#0{"array_comp"} <%[[VAL_11]]> (%[[VAL_9]]:%[[VAL_15]]:%[[VAL_12]], %[[VAL_10]]:%[[VAL_17]]:%[[VAL_12]]) imag shape %[[VAL_30]] : (!fir.ref>}>>, !fir.shapeshift<2>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.box> end subroutine + +subroutine test_poly_array_vector_subscript(p, v, r) + use comp_ref + class(t1),pointer :: p(:) + integer v(3) + integer r(3) + r = p(v)%scalar_i +end subroutine test_poly_array_vector_subscript +! CHECK-LABEL: func.func @_QPtest_poly_array_vector_subscript( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>>> {fir.bindc_name = "p"}, +! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref> {fir.bindc_name = "v"}, +! CHECK-SAME: %[[VAL_2:.*]]: !fir.ref> {fir.bindc_name = "r"}) { +! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest_poly_array_vector_subscriptEp"} : (!fir.ref>>>>) -> (!fir.ref>>>>, !fir.ref>>>>) +! CHECK: %[[VAL_4:.*]] = arith.constant 3 : index +! CHECK: %[[VAL_5:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_2]](%[[VAL_5]]) {uniq_name = "_QFtest_poly_array_vector_subscriptEr"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) +! CHECK: %[[VAL_7:.*]] = arith.constant 3 : index +! CHECK: %[[VAL_8:.*]] = fir.shape %[[VAL_7]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_1]](%[[VAL_8]]) {uniq_name = "_QFtest_poly_array_vector_subscriptEv"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) +! CHECK: %[[VAL_10:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref>>>> +! CHECK: %[[VAL_11:.*]] = hlfir.elemental %[[VAL_8]] unordered : (!fir.shape<1>) -> !hlfir.expr<3xi64> { +! CHECK: ^bb0(%[[VAL_12:.*]]: index): +! CHECK: %[[VAL_13:.*]] = hlfir.designate %[[VAL_9]]#0 (%[[VAL_12]]) : (!fir.ref>, index) -> !fir.ref +! CHECK: %[[VAL_14:.*]] = fir.load %[[VAL_13]] : !fir.ref +! CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (i32) -> i64 +! CHECK: hlfir.yield_element %[[VAL_15]] : i64 +! CHECK: } +! CHECK: %[[VAL_16:.*]] = arith.constant 3 : index +! CHECK: %[[VAL_17:.*]] = fir.shape %[[VAL_16]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_18:.*]] = hlfir.elemental %[[VAL_17]] unordered : (!fir.shape<1>) -> !hlfir.expr<3xi32> { +! CHECK: ^bb0(%[[VAL_19:.*]]: index): +! CHECK: %[[VAL_20:.*]] = hlfir.apply %[[VAL_11]], %[[VAL_19]] : (!hlfir.expr<3xi64>, index) -> i64 +! CHECK: %[[VAL_21:.*]] = hlfir.designate %[[VAL_10]] (%[[VAL_20]]) : (!fir.class>>>, i64) -> !fir.class> +! CHECK: %[[VAL_22:.*]] = hlfir.designate %[[VAL_21]]{"scalar_i"} : (!fir.class>) -> !fir.ref +! CHECK: %[[VAL_23:.*]] = fir.load %[[VAL_22]] : !fir.ref +! CHECK: hlfir.yield_element %[[VAL_23]] : i32 +! CHECK: } +! CHECK: hlfir.assign %[[VAL_18]] to %[[VAL_6]]#0 : !hlfir.expr<3xi32>, !fir.ref> +! CHECK: hlfir.destroy %[[VAL_18]] : !hlfir.expr<3xi32> +! CHECK: hlfir.destroy %[[VAL_11]] : !hlfir.expr<3xi64> +! CHECK: return +! CHECK: }