Skip to content

Commit 1bd0ff7

Browse files
committed
[flang] Allow non polymorphic pointer assignment with polymorphic rhs
Remove the TODO and allow pointer assignment with non polymorphic entity on the lhs. The assignment follow the same scheme as derived-type pointer assignment to parent component. Reviewed By: jeanPerier Differential Revision: https://reviews.llvm.org/D138998
1 parent b802b53 commit 1bd0ff7

File tree

2 files changed

+34
-16
lines changed

2 files changed

+34
-16
lines changed

flang/lib/Lower/Bridge.cpp

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2710,22 +2710,6 @@ class FirConverter : public Fortran::lower::AbstractConverter {
27102710
[&](const Fortran::evaluate::Assignment::BoundsSpec &lbExprs) {
27112711
if (Fortran::evaluate::IsProcedure(assign.rhs))
27122712
TODO(loc, "procedure pointer assignment");
2713-
std::optional<Fortran::evaluate::DynamicType> lhsType =
2714-
assign.lhs.GetType();
2715-
std::optional<Fortran::evaluate::DynamicType> rhsType =
2716-
assign.rhs.GetType();
2717-
// Polymorphic lhs/rhs may need more care. See F2018 10.2.2.3.
2718-
// If the pointer object is not polymorphic (7.3.2.3) and the
2719-
// pointer target is polymorphic with dynamic type that differs
2720-
// from its declared type, the assignment target is the ancestor
2721-
// component of the pointer target that has the type of the
2722-
// pointer object. Otherwise, the assignment target is the pointer
2723-
// target.
2724-
if ((lhsType && !lhsType->IsPolymorphic()) &&
2725-
(rhsType && rhsType->IsPolymorphic()))
2726-
TODO(loc, "non-polymorphic pointer assignment with polymorphic "
2727-
"entity on rhs");
2728-
27292713
llvm::SmallVector<mlir::Value> lbounds;
27302714
for (const Fortran::evaluate::ExtentExpr &lbExpr : lbExprs)
27312715
lbounds.push_back(

flang/test/Lower/polymorphic.f90

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,4 +219,38 @@ subroutine no_reassoc_poly_value(a, i)
219219
! CHECK: %[[EMBOX:.*]] = fir.embox %[[TEMP]] tdesc %[[TDESC]] : (!fir.ref<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>, !fir.tdesc<none>) -> !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>
220220
! CHECK: fir.call @_QMpolymorphic_testPtakes_p1(%[[EMBOX]]) {{.*}} : (!fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) -> ()
221221

222+
! Test pointer assignment with non polymorphic lhs and polymorphic rhs
223+
224+
subroutine pointer_assign_parent(p)
225+
type(p2), target :: p
226+
type(p1), pointer :: tp
227+
tp => p%p1
228+
end subroutine
229+
230+
! First test is here to have a reference with non polymorphic on both sides.
231+
! CHECK-LABEL: func.func @_QMpolymorphic_testPpointer_assign_parent(
232+
! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.type<_QMpolymorphic_testTp2{a:i32,b:i32,c:f32}>> {fir.bindc_name = "p", fir.target}) {
233+
! CHECK: %[[TP:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>> {bindc_name = "tp", uniq_name = "_QMpolymorphic_testFpointer_assign_parentEtp"}
234+
! CHECK: %[[PTR:.*]] = fir.alloca !fir.ptr<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {uniq_name = "_QMpolymorphic_testFpointer_assign_parentEtp.addr"}
235+
! CHECK: %[[ZERO:.*]] = fir.zero_bits !fir.ptr<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>
236+
! CHECK: fir.store %[[ZERO]] to %[[PTR]] : !fir.ref<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>
237+
! CHECK: %[[CONVERT:.*]] = fir.convert %[[ARG0]] : (!fir.ref<!fir.type<_QMpolymorphic_testTp2{a:i32,b:i32,c:f32}>>) -> !fir.ptr<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>
238+
! CHECK: fir.store %[[CONVERT]] to %[[PTR]] : !fir.ref<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>
239+
240+
subroutine pointer_assign_non_poly(p)
241+
class(p1), target :: p
242+
type(p1), pointer :: tp
243+
tp => p
244+
end subroutine
245+
246+
! CHECK-LABEL: func.func @_QMpolymorphic_testPpointer_assign_non_poly(
247+
! CHECK-SAME: %arg0: !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {fir.bindc_name = "p", fir.target}) {
248+
! CHECK: %[[TP:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>> {bindc_name = "tp", uniq_name = "_QMpolymorphic_testFpointer_assign_non_polyEtp"}
249+
! CHECK: %[[PTR:.*]] = fir.alloca !fir.ptr<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {uniq_name = "_QMpolymorphic_testFpointer_assign_non_polyEtp.addr"}
250+
! CHECK: %[[ZERO:.*]] = fir.zero_bits !fir.ptr<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>
251+
! CHECK: fir.store %[[ZERO]] to %[[PTR]] : !fir.ref<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>
252+
! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[ARG0]] : (!fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) -> !fir.ref<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>
253+
! CHECK: %[[CONVERT:.*]] = fir.convert %3 : (!fir.ref<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) -> !fir.ptr<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>
254+
! CHECK: fir.store %[[CONVERT]] to %[[PTR]] : !fir.ref<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>
255+
222256
end module

0 commit comments

Comments
 (0)