@@ -1275,12 +1275,14 @@ static void instantiateCommon(Fortran::lower::AbstractConverter &converter,
1275
1275
1276
1276
// / Helper to decide if a dummy argument must be tracked in an BoxValue.
1277
1277
static bool lowerToBoxValue (const Fortran::semantics::Symbol &sym,
1278
- mlir::Value dummyArg) {
1278
+ mlir::Value dummyArg,
1279
+ Fortran::lower::AbstractConverter &converter) {
1279
1280
// Only dummy arguments coming as fir.box can be tracked in an BoxValue.
1280
1281
if (!dummyArg || !dummyArg.getType ().isa <fir::BaseBoxType>())
1281
1282
return false ;
1282
1283
// Non contiguous arrays must be tracked in an BoxValue.
1283
- if (sym.Rank () > 0 && !sym.attrs ().test (Fortran::semantics::Attr::CONTIGUOUS))
1284
+ if (sym.Rank () > 0 && !Fortran::evaluate::IsSimplyContiguous (
1285
+ sym, converter.getFoldingContext ()))
1284
1286
return true ;
1285
1287
// Assumed rank and optional fir.box cannot yet be read while lowering the
1286
1288
// specifications.
@@ -1713,16 +1715,60 @@ void Fortran::lower::mapSymbolAttributes(
1713
1715
1714
1716
if (isDummy) {
1715
1717
mlir::Value dummyArg = symMap.lookupSymbol (sym).getAddr ();
1716
- if (lowerToBoxValue (sym, dummyArg)) {
1718
+ if (lowerToBoxValue (sym, dummyArg, converter )) {
1717
1719
llvm::SmallVector<mlir::Value> lbounds;
1718
1720
llvm::SmallVector<mlir::Value> explicitExtents;
1719
1721
llvm::SmallVector<mlir::Value> explicitParams;
1720
1722
// Lower lower bounds, explicit type parameters and explicit
1721
1723
// extents if any.
1722
- if (ba.isChar ())
1724
+ if (ba.isChar ()) {
1723
1725
if (mlir::Value len =
1724
1726
lowerExplicitCharLen (converter, loc, ba, symMap, stmtCtx))
1725
1727
explicitParams.push_back (len);
1728
+ if (sym.Rank () == 0 ) {
1729
+ // Do not keep scalar characters as fir.box (even when optional).
1730
+ // Lowering and FIR is not meant to deal with scalar characters as
1731
+ // fir.box outside of calls.
1732
+ auto boxTy = dummyArg.getType ().dyn_cast <fir::BaseBoxType>();
1733
+ mlir::Type refTy = builder.getRefType (boxTy.getEleTy ());
1734
+ mlir::Type lenType = builder.getCharacterLengthType ();
1735
+ mlir::Value addr, len;
1736
+ if (Fortran::semantics::IsOptional (sym)) {
1737
+ auto isPresent = builder.create <fir::IsPresentOp>(
1738
+ loc, builder.getI1Type (), dummyArg);
1739
+ auto addrAndLen =
1740
+ builder
1741
+ .genIfOp (loc, {refTy, lenType}, isPresent,
1742
+ /* withElseRegion=*/ true )
1743
+ .genThen ([&]() {
1744
+ mlir::Value readAddr =
1745
+ builder.create <fir::BoxAddrOp>(loc, refTy, dummyArg);
1746
+ mlir::Value readLength =
1747
+ charHelp.readLengthFromBox (dummyArg);
1748
+ builder.create <fir::ResultOp>(
1749
+ loc, mlir::ValueRange{readAddr, readLength});
1750
+ })
1751
+ .genElse ([&] {
1752
+ mlir::Value readAddr = builder.genAbsentOp (loc, refTy);
1753
+ mlir::Value readLength =
1754
+ fir::factory::createZeroValue (builder, loc, lenType);
1755
+ builder.create <fir::ResultOp>(
1756
+ loc, mlir::ValueRange{readAddr, readLength});
1757
+ })
1758
+ .getResults ();
1759
+ addr = addrAndLen[0 ];
1760
+ len = addrAndLen[1 ];
1761
+ } else {
1762
+ addr = builder.create <fir::BoxAddrOp>(loc, refTy, dummyArg);
1763
+ len = charHelp.readLengthFromBox (dummyArg);
1764
+ }
1765
+ if (!explicitParams.empty ())
1766
+ len = explicitParams[0 ];
1767
+ ::genDeclareSymbol (converter, symMap, sym, addr, len, /* extents=*/ {},
1768
+ /* lbounds=*/ {}, replace);
1769
+ return ;
1770
+ }
1771
+ }
1726
1772
// TODO: derived type length parameters.
1727
1773
lowerExplicitLowerBounds (converter, loc, ba, lbounds, symMap, stmtCtx);
1728
1774
lowerExplicitExtents (converter, loc, ba, lbounds, explicitExtents, symMap,
0 commit comments