diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp --- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp +++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp @@ -4925,8 +4925,11 @@ builder.getKindMap().getIntegerBitsize(fir::toInt(constOp))); } - if (box.getType().isa()) + if (args[0].getBoxOf()) { + box = builder.createBox(loc, args[0], /*isPolymorphic=*/true); + } else if (box.getType().isa()) { box = builder.create(loc, box); + } mlir::Value eleSize = builder.create(loc, kindTy, box); mlir::Value c8 = builder.createIntegerConstant(loc, kindTy, 8); return builder.create(loc, eleSize, c8); diff --git a/flang/test/Lower/Intrinsics/storage_size.f90 b/flang/test/Lower/Intrinsics/storage_size.f90 --- a/flang/test/Lower/Intrinsics/storage_size.f90 +++ b/flang/test/Lower/Intrinsics/storage_size.f90 @@ -9,6 +9,10 @@ integer :: b end type + type :: p3 + class(p1), pointer :: p(:) + end type + contains integer function unlimited_polymorphic_pointer(p) result(size) @@ -113,4 +117,29 @@ ! CHECK: %[[RES:.*]] = fir.load %[[SIZE]] : !fir.ref ! CHECK: return %[[RES]] : i64 + integer function polymorphic_value(t) result(size) + type(p3) :: t + size = storage_size(t%p(1)) + end function + +! CHECK-LABEL: func.func @_QMstorage_size_testPpolymorphic_value( +! CHECK-SAME: %[[T:.*]]: !fir.ref>>>}>> {fir.bindc_name = "t"}) -> i32 { +! CHECK: %[[ALLOCA:.*]] = fir.alloca i32 {bindc_name = "size", uniq_name = "_QMstorage_size_testFpolymorphic_valueEsize"} +! CHECK: %[[FIELD_P:.*]] = fir.field_index p, !fir.type<_QMstorage_size_testTp3{p:!fir.class>>>}> +! CHECK: %[[COORD_P:.*]] = fir.coordinate_of %[[T]], %[[FIELD_P]] : (!fir.ref>>>}>>, !fir.field) -> !fir.ref>>>> +! CHECK: %[[LOAD_COORD_P:.*]] = fir.load %[[COORD_P]] : !fir.ref>>>> +! CHECK: %[[C0:.*]] = arith.constant 0 : index +! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[LOAD_COORD_P]], %[[C0]] : (!fir.class>>>, index) -> (index, index, index) +! CHECK: %[[C1:.*]] = arith.constant 1 : i64 +! CHECK: %[[DIMI64:.*]] = fir.convert %[[BOX_DIMS]]#0 : (index) -> i64 +! CHECK: %[[IDX:.*]] = arith.subi %[[C1]], %[[DIMI64]] : i64 +! CHECK: %[[COORD_OF:.*]] = fir.coordinate_of %[[LOAD_COORD_P]], %[[IDX]] : (!fir.class>>>, i64) -> !fir.ref> +! CHECK: %[[BOXED:.*]] = fir.embox %[[COORD_OF]] source_box %[[LOAD_COORD_P]] : (!fir.ref>, !fir.class>>>) -> !fir.class> +! CHECK: %[[ELE_SIZE:.*]] = fir.box_elesize %[[BOXED]] : (!fir.class>) -> i32 +! CHECK: %[[C8:.*]] = arith.constant 8 : i32 +! CHECK: %[[SIZE:.*]] = arith.muli %[[ELE_SIZE]], %[[C8]] : i32 +! CHECK: fir.store %[[SIZE]] to %[[ALLOCA]] : !fir.ref +! CHECK: %[[RET:.*]] = fir.load %[[ALLOCA]] : !fir.ref +! CHECK: return %[[RET]] : i32 + end module