Index: flang/include/flang/Lower/Allocatable.h =================================================================== --- flang/include/flang/Lower/Allocatable.h +++ flang/include/flang/Lower/Allocatable.h @@ -57,6 +57,10 @@ const fir::MutableBoxValue &box, mlir::Location loc, mlir::Value declaredTypeDesc = {}); +fir::MutableProperties +getMutableProperties(AbstractConverter &converter, mlir::Location loc, + const Fortran::semantics::Symbol &sym); + /// Create a MutableBoxValue for an allocatable or pointer entity. /// If the variables is a local variable that is not a dummy, it will be /// initialized to unallocated/diassociated status. Index: flang/lib/Lower/Allocatable.cpp =================================================================== --- flang/lib/Lower/Allocatable.cpp +++ flang/lib/Lower/Allocatable.cpp @@ -907,6 +907,36 @@ return mutableProperties; } +fir::MutableProperties Fortran::lower::getMutableProperties( + Fortran::lower::AbstractConverter &converter, mlir::Location loc, + const Fortran::semantics::Symbol &sym) { + fir::FirOpBuilder &builder = converter.getFirOpBuilder(); + fir::MutableProperties mutableProperties; + std::string name = converter.mangleName(sym); + mlir::Type baseAddrTy = converter.genType(sym); + if (auto boxType = baseAddrTy.dyn_cast()) + baseAddrTy = boxType.getEleTy(); + // Allocate and set a variable to hold the address. + // It will be set to null in setUnallocatedStatus. + mutableProperties.addr = builder.allocateLocal( + loc, baseAddrTy, name + ".addr", "", + /*shape=*/std::nullopt, /*typeparams=*/std::nullopt); + // Allocate variables to hold lower bounds and extents. + int rank = sym.Rank(); + mlir::Type idxTy = builder.getIndexType(); + for (decltype(rank) i = 0; i < rank; ++i) { + mlir::Value lboundVar = builder.allocateLocal( + loc, idxTy, name + ".lb" + std::to_string(i), "", + /*shape=*/std::nullopt, /*typeparams=*/std::nullopt); + mlir::Value extentVar = builder.allocateLocal( + loc, idxTy, name + ".ext" + std::to_string(i), "", + /*shape=*/std::nullopt, /*typeparams=*/std::nullopt); + mutableProperties.lbounds.emplace_back(lboundVar); + mutableProperties.extents.emplace_back(extentVar); + } + return mutableProperties; +} + fir::MutableBoxValue Fortran::lower::createMutableBox( Fortran::lower::AbstractConverter &converter, mlir::Location loc, const Fortran::lower::pft::Variable &var, mlir::Value boxAddr, Index: flang/lib/Lower/Bridge.cpp =================================================================== --- flang/lib/Lower/Bridge.cpp +++ flang/lib/Lower/Bridge.cpp @@ -568,12 +568,15 @@ const auto *details = sym.detailsIf(); assert(details && "No host-association found"); const Fortran::semantics::Symbol &hsym = details->symbol(); + mlir::Type hSymType = genType(hsym); Fortran::lower::SymbolBox hsb = lookupSymbol(hsym); auto allocate = [&](llvm::ArrayRef shape, llvm::ArrayRef typeParams) -> mlir::Value { mlir::Value allocVal = builder->allocateLocal( - loc, symType, mangleName(sym), toStringRef(sym.GetUltimate().name()), + loc, + Fortran::semantics::IsAllocatableOrPointer(hsym) ? hSymType : symType, + mangleName(sym), toStringRef(sym.GetUltimate().name()), /*pinned=*/true, shape, typeParams, sym.GetUltimate().attrs().test(Fortran::semantics::Attr::TARGET)); return allocVal; @@ -601,8 +604,13 @@ [&](const fir::MutableBoxValue &box) -> fir::ExtendedValue { // Allocate storage for a pointer/allocatble descriptor. // No shape/lengths to be passed to the alloca. - return fir::MutableBoxValue(allocate({}, {}), - box.nonDeferredLenParams(), {}); + fir::MutableProperties mutableProperties = + Fortran::lower::getMutableProperties(*this, loc, hsym); + fir::MutableBoxValue privateBox( + allocate({}, {}), box.nonDeferredLenParams(), mutableProperties); + fir::factory::disassociateMutableBox(*builder, loc, privateBox, + /*polymorphicSetType=*/false); + return privateBox; }, [&](const auto &) -> fir::ExtendedValue { mlir::Value temp = @@ -882,9 +890,9 @@ fir::ExtendedValue getExtendedValue(Fortran::lower::SymbolBox sb) { fir::ExtendedValue exv = symBoxToExtendedValue(sb); // Dereference pointers and allocatables. - if (const auto *box = exv.getBoxOf()) - return fir::factory::genMutableBoxRead(*builder, getCurrentLocation(), - *box); + // if (const auto *box = exv.getBoxOf()) + // return fir::factory::genMutableBoxRead(*builder, getCurrentLocation(), + // *box); return exv; }