Skip to content

Commit 483737c

Browse files
committed
Lower length expr to max(expr, 0) - cover dummy case
#1276 missed the case where the character with explicit length is a dummy argument. Cover this here and update more tests.
1 parent a5aa287 commit 483737c

File tree

6 files changed

+254
-201
lines changed

6 files changed

+254
-201
lines changed

flang/include/flang/Lower/ConvertExpr.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,10 @@ inline mlir::NamedAttribute getAdaptToByRefAttr(fir::FirOpBuilder &builder) {
210210
builder.getUnitAttr()};
211211
}
212212

213+
/// Generate max(\p value, 0) where \p value is a scalar integer.
214+
mlir::Value genMaxWithZero(fir::FirOpBuilder &builder, mlir::Location loc,
215+
mlir::Value value);
216+
213217
} // namespace Fortran::lower
214218

215219
#endif // FORTRAN_LOWER_CONVERTEXPR_H

flang/lib/Lower/ConvertExpr.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1755,6 +1755,8 @@ class ScalarExprLowering {
17551755
if (const Fortran::semantics::MaybeIntExpr &lenExpr =
17561756
type->characterTypeSpec().length().GetExplicit()) {
17571757
mlir::Value len = fir::getBase(genval(*lenExpr));
1758+
// F2018 7.4.4.2 point 5.
1759+
len = Fortran::lower::genMaxWithZero(builder, getLoc(), len);
17581760
symMap.addSymbol(*arg,
17591761
replaceScalarCharacterLength(gen(*expr), len));
17601762
continue;
@@ -6298,3 +6300,15 @@ void Fortran::lower::createArrayMergeStores(
62986300
esp.resetBindings();
62996301
esp.incrementCounter();
63006302
}
6303+
6304+
mlir::Value Fortran::lower::genMaxWithZero(fir::FirOpBuilder &builder,
6305+
mlir::Location loc,
6306+
mlir::Value value) {
6307+
mlir::Value zero = builder.createIntegerConstant(loc, value.getType(), 0);
6308+
if (auto definingOp = value.getDefiningOp())
6309+
if (auto cst = mlir::dyn_cast<mlir::arith::ConstantOp>(definingOp))
6310+
if (auto intAttr = cst.value().dyn_cast<mlir::IntegerAttr>())
6311+
return intAttr.getInt() < 0 ? zero : value;
6312+
return Fortran::lower::genMax(builder, loc,
6313+
llvm::SmallVector<mlir::Value>{value, zero});
6314+
}

flang/lib/Lower/ConvertVariable.cpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1248,9 +1248,7 @@ void Fortran::lower::mapSymbolAttributes(
12481248
auto rawLen = genValue(*charLen);
12491249
// If the length expression is negative, the length is zero. See
12501250
// F2018 7.4.4.2 point 5.
1251-
auto zero = builder.createIntegerConstant(loc, rawLen.getType(), 0);
1252-
return Fortran::lower::genMax(builder, loc,
1253-
llvm::SmallVector<mlir::Value>{rawLen, zero});
1251+
return genMaxWithZero(builder, loc, rawLen);
12541252
};
12551253

12561254
ba.match(
@@ -1329,7 +1327,7 @@ void Fortran::lower::mapSymbolAttributes(
13291327
}
13301328
// Override LEN with an expression
13311329
if (charLen)
1332-
len = genValue(*charLen);
1330+
len = genExplicitCharLen(charLen);
13331331
symMap.addCharSymbol(sym, boxAddr, len, true);
13341332
return;
13351333
}
@@ -1491,15 +1489,15 @@ void Fortran::lower::mapSymbolAttributes(
14911489
addr = unboxchar.first;
14921490
if (charLen) {
14931491
// Set/override LEN with an expression
1494-
len = genValue(*charLen);
1492+
len = genExplicitCharLen(charLen);
14951493
} else {
14961494
// LEN is from the boxchar
14971495
len = unboxchar.second;
14981496
mustBeDummy = true;
14991497
}
15001498
} else {
15011499
// local CHARACTER variable
1502-
len = genExplicitCharLen(*charLen);
1500+
len = genExplicitCharLen(charLen);
15031501
}
15041502
llvm::SmallVector<mlir::Value> lengths = {len};
15051503

@@ -1617,7 +1615,7 @@ void Fortran::lower::mapSymbolAttributes(
16171615
addr = builder.create<fir::BoxAddrOp>(loc, refTy, argBox);
16181616
if (charLen)
16191617
// Set/override LEN with an expression.
1620-
len = genValue(*charLen);
1618+
len = genExplicitCharLen(charLen);
16211619
else
16221620
// Get the length from the actual arguments.
16231621
len = charHelp.readLengthFromBox(argBox);
@@ -1626,15 +1624,15 @@ void Fortran::lower::mapSymbolAttributes(
16261624
addr = unboxchar.first;
16271625
if (charLen) {
16281626
// Set/override LEN with an expression
1629-
len = genValue(*charLen);
1627+
len = genExplicitCharLen(charLen);
16301628
} else {
16311629
// Get the length from the actual arguments.
16321630
len = unboxchar.second;
16331631
}
16341632
}
16351633
} else {
16361634
// local CHARACTER variable
1637-
len = genExplicitCharLen(*charLen);
1635+
len = genExplicitCharLen(charLen);
16381636
}
16391637
llvm::SmallVector<mlir::Value> lengths = {len};
16401638

0 commit comments

Comments
 (0)