@@ -4813,40 +4813,22 @@ class FirConverter : public Fortran::lower::AbstractConverter {
48134813
48144814 // Generate pointer assignment with possibly empty bounds-spec. R1035: a
48154815 // bounds-spec is a lower bound value.
4816- void genPointerAssignment (
4816+ void genNoHLFIRPointerAssignment (
48174817 mlir::Location loc, const Fortran::evaluate::Assignment &assign,
48184818 const Fortran::evaluate::Assignment::BoundsSpec &lbExprs) {
48194819 Fortran::lower::StatementContext stmtCtx;
48204820
4821- if (!lowerToHighLevelFIR () &&
4822- Fortran::evaluate::IsProcedureDesignator (assign.rhs ))
4821+ assert (!lowerToHighLevelFIR () && " code should not be called with HFLIR " );
4822+ if ( Fortran::evaluate::IsProcedureDesignator (assign.rhs ))
48234823 TODO (loc, " procedure pointer assignment" );
4824- if (Fortran::evaluate::IsProcedurePointer (assign.lhs )) {
4825- hlfir::Entity lhs = Fortran::lower::convertExprToHLFIR (
4826- loc, *this , assign.lhs , localSymbols, stmtCtx);
4827- if (Fortran::evaluate::UnwrapExpr<Fortran::evaluate::NullPointer>(
4828- assign.rhs )) {
4829- // rhs is null(). rhs being null(pptr) is handled in genNull.
4830- auto boxTy{
4831- Fortran::lower::getUntypedBoxProcType (builder->getContext ())};
4832- hlfir::Entity rhs (
4833- fir::factory::createNullBoxProc (*builder, loc, boxTy));
4834- builder->createStoreWithConvert (loc, rhs, lhs);
4835- return ;
4836- }
4837- hlfir::Entity rhs (getBase (Fortran::lower::convertExprToAddress (
4838- loc, *this , assign.rhs , localSymbols, stmtCtx)));
4839- builder->createStoreWithConvert (loc, rhs, lhs);
4840- return ;
4841- }
48424824
48434825 std::optional<Fortran::evaluate::DynamicType> lhsType =
48444826 assign.lhs .GetType ();
48454827 // Delegate pointer association to unlimited polymorphic pointer
48464828 // to the runtime. element size, type code, attribute and of
48474829 // course base_addr might need to be updated.
48484830 if (lhsType && lhsType->IsPolymorphic ()) {
4849- if (! lowerToHighLevelFIR () && explicitIterationSpace ())
4831+ if (explicitIterationSpace ())
48504832 TODO (loc, " polymorphic pointer assignment in FORALL" );
48514833 llvm::SmallVector<mlir::Value> lbounds;
48524834 for (const Fortran::evaluate::ExtentExpr &lbExpr : lbExprs)
@@ -4873,7 +4855,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
48734855 llvm::SmallVector<mlir::Value> lbounds;
48744856 for (const Fortran::evaluate::ExtentExpr &lbExpr : lbExprs)
48754857 lbounds.push_back (fir::getBase (genExprValue (toEvExpr (lbExpr), stmtCtx)));
4876- if (! lowerToHighLevelFIR () && explicitIterationSpace ()) {
4858+ if (explicitIterationSpace ()) {
48774859 // Pointer assignment in FORALL context. Copy the rhs box value
48784860 // into the lhs box variable.
48794861 genArrayAssignment (assign, stmtCtx, lbounds);
@@ -4884,6 +4866,21 @@ class FirConverter : public Fortran::lower::AbstractConverter {
48844866 stmtCtx);
48854867 }
48864868
4869+ void genPointerAssignment (mlir::Location loc,
4870+ const Fortran::evaluate::Assignment &assign) {
4871+ if (isInsideHlfirForallOrWhere ()) {
4872+ // Generate Pointer assignment as hlfir.region_assign.
4873+ genForallPointerAssignment (loc, assign);
4874+ return ;
4875+ }
4876+ Fortran::lower::StatementContext stmtCtx;
4877+ hlfir::Entity lhs = Fortran::lower::convertExprToHLFIR (
4878+ loc, *this , assign.lhs , localSymbols, stmtCtx);
4879+ mlir::Value rhs = genPointerAssignmentRhs (loc, lhs, assign, stmtCtx);
4880+ builder->createStoreWithConvert (loc, rhs, lhs);
4881+ cuf::genPointerSync (lhs, *builder);
4882+ }
4883+
48874884 void genForallPointerAssignment (mlir::Location loc,
48884885 const Fortran::evaluate::Assignment &assign) {
48894886 // Lower pointer assignment inside forall with hlfir.region_assign with
@@ -4904,8 +4901,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
49044901 // Lower RHS in its own region.
49054902 builder->createBlock (®ionAssignOp.getRhsRegion ());
49064903 Fortran::lower::StatementContext rhsContext;
4907- mlir::Value rhs =
4908- genForallPointerAssignmentRhs (loc, lhs, assign, rhsContext);
4904+ mlir::Value rhs = genPointerAssignmentRhs (loc, lhs, assign, rhsContext);
49094905 auto rhsYieldOp = hlfir::YieldOp::create (*builder, loc, rhs);
49104906 Fortran::lower::genCleanUpInRegionIfAny (
49114907 loc, *builder, rhsYieldOp.getCleanup (), rhsContext);
@@ -4921,9 +4917,9 @@ class FirConverter : public Fortran::lower::AbstractConverter {
49214917 }
49224918
49234919 mlir::Value
4924- genForallPointerAssignmentRhs (mlir::Location loc, mlir::Value lhs,
4925- const Fortran::evaluate::Assignment &assign,
4926- Fortran::lower::StatementContext &rhsContext) {
4920+ genPointerAssignmentRhs (mlir::Location loc, hlfir::Entity lhs,
4921+ const Fortran::evaluate::Assignment &assign,
4922+ Fortran::lower::StatementContext &rhsContext) {
49274923 if (Fortran::evaluate::IsProcedureDesignator (assign.lhs )) {
49284924 if (Fortran::evaluate::UnwrapExpr<Fortran::evaluate::NullPointer>(
49294925 assign.rhs ))
@@ -4935,11 +4931,34 @@ class FirConverter : public Fortran::lower::AbstractConverter {
49354931 // Data target.
49364932 auto lhsBoxType =
49374933 llvm::cast<fir::BaseBoxType>(fir::unwrapRefType (lhs.getType ()));
4938- // For NULL, create disassociated descriptor whose dynamic type is
4939- // the static type of the LHS.
4934+ // For NULL, create disassociated descriptor whose dynamic type is the
4935+ // static type of the LHS (fulfills 7.3.2.3 requirements that the dynamic
4936+ // type of a deallocated polymorphic pointer is its static type).
49404937 if (Fortran::evaluate::UnwrapExpr<Fortran::evaluate::NullPointer>(
4941- assign.rhs ))
4942- return fir::factory::createUnallocatedBox (*builder, loc, lhsBoxType, {});
4938+ assign.rhs )) {
4939+ llvm::SmallVector<mlir::Value, 1 > nonDeferredLenParams;
4940+ if (auto lhsVar =
4941+ llvm::dyn_cast_if_present<fir::FortranVariableOpInterface>(
4942+ lhs.getDefiningOp ()))
4943+ nonDeferredLenParams = lhsVar.getExplicitTypeParams ();
4944+ if (isInsideHlfirForallOrWhere ()) {
4945+ // Inside FORALL, the non deferred type parameters may only be
4946+ // accessible in the hlfir.region_assign lhs region if they were
4947+ // computed there.
4948+ for (mlir::Value ¶m : nonDeferredLenParams)
4949+ if (!param.getParentRegion ()->isAncestor (
4950+ builder->getBlock ()->getParent ())) {
4951+ if (llvm::isa_and_nonnull<mlir::arith::ConstantOp>(
4952+ param.getDefiningOp ()))
4953+ param = builder->clone (*param.getDefiningOp ())->getResult (0 );
4954+ else
4955+ TODO (loc, " Pointer assignment with non deferred type parameter "
4956+ " inside FORALL" );
4957+ }
4958+ }
4959+ return fir::factory::createUnallocatedBox (*builder, loc, lhsBoxType,
4960+ nonDeferredLenParams);
4961+ }
49434962 hlfir::Entity rhs = Fortran::lower::convertExprToHLFIR (
49444963 loc, *this , assign.rhs , localSymbols, rhsContext);
49454964 auto rhsBoxType = rhs.getBoxType ();
@@ -5032,9 +5051,10 @@ class FirConverter : public Fortran::lower::AbstractConverter {
50325051
50335052 // Pointer assignment with bounds-remapping. R1036: a bounds-remapping is a
50345053 // pair, lower bound and upper bound.
5035- void genPointerAssignment (
5054+ void genNoHLFIRPointerAssignment (
50365055 mlir::Location loc, const Fortran::evaluate::Assignment &assign,
50375056 const Fortran::evaluate::Assignment::BoundsRemapping &boundExprs) {
5057+ assert (!lowerToHighLevelFIR () && " code should not be called with HFLIR" );
50385058 Fortran::lower::StatementContext stmtCtx;
50395059 llvm::SmallVector<mlir::Value> lbounds;
50405060 llvm::SmallVector<mlir::Value> ubounds;
@@ -5053,7 +5073,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
50535073 // Polymorphic lhs/rhs need more care. See F2018 10.2.2.3.
50545074 if ((lhsType && lhsType->IsPolymorphic ()) ||
50555075 (rhsType && rhsType->IsPolymorphic ())) {
5056- if (! lowerToHighLevelFIR () && explicitIterationSpace ())
5076+ if (explicitIterationSpace ())
50575077 TODO (loc, " polymorphic pointer assignment in FORALL" );
50585078
50595079 fir::MutableBoxValue lhsMutableBox = genExprMutableBox (loc, assign.lhs );
@@ -5071,7 +5091,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
50715091 rhsType->IsPolymorphic ());
50725092 return ;
50735093 }
5074- if (! lowerToHighLevelFIR () && explicitIterationSpace ()) {
5094+ if (explicitIterationSpace ()) {
50755095 // Pointer assignment in FORALL context. Copy the rhs box value
50765096 // into the lhs box variable.
50775097 genArrayAssignment (assign, stmtCtx, lbounds, ubounds);
@@ -5083,13 +5103,6 @@ class FirConverter : public Fortran::lower::AbstractConverter {
50835103 fir::factory::disassociateMutableBox (*builder, loc, lhs);
50845104 return ;
50855105 }
5086- if (lowerToHighLevelFIR ()) {
5087- fir::ExtendedValue rhs = genExprAddr (assign.rhs , stmtCtx);
5088- fir::factory::associateMutableBoxWithRemap (*builder, loc, lhs, rhs,
5089- lbounds, ubounds);
5090- return ;
5091- }
5092- // Legacy lowering below.
50935106 // Do not generate a temp in case rhs is an array section.
50945107 fir::ExtendedValue rhs =
50955108 Fortran::lower::isArraySectionWithoutVectorSubscript (assign.rhs )
@@ -5479,18 +5492,10 @@ class FirConverter : public Fortran::lower::AbstractConverter {
54795492 dirs);
54805493 },
54815494 [&](const Fortran::evaluate::Assignment::BoundsSpec &lbExprs) {
5482- if (isInsideHlfirForallOrWhere ())
5483- genForallPointerAssignment (loc, assign);
5484- else
5485- genPointerAssignment (loc, assign, lbExprs);
5495+ genPointerAssignment (loc, assign);
54865496 },
54875497 [&](const Fortran::evaluate::Assignment::BoundsRemapping
5488- &boundExprs) {
5489- if (isInsideHlfirForallOrWhere ())
5490- genForallPointerAssignment (loc, assign);
5491- else
5492- genPointerAssignment (loc, assign, boundExprs);
5493- },
5498+ &boundExprs) { genPointerAssignment (loc, assign); },
54945499 },
54955500 assign.u );
54965501 return ;
@@ -5692,11 +5697,11 @@ class FirConverter : public Fortran::lower::AbstractConverter {
56925697 },
56935698
56945699 [&](const Fortran::evaluate::Assignment::BoundsSpec &lbExprs) {
5695- return genPointerAssignment (loc, assign, lbExprs);
5700+ return genNoHLFIRPointerAssignment (loc, assign, lbExprs);
56965701 },
56975702 [&](const Fortran::evaluate::Assignment::BoundsRemapping
56985703 &boundExprs) {
5699- return genPointerAssignment (loc, assign, boundExprs);
5704+ return genNoHLFIRPointerAssignment (loc, assign, boundExprs);
57005705 },
57015706 },
57025707 assign.u );
0 commit comments