Skip to content

Commit 2fe26ba

Browse files
committed
Fix for issue #403 (and duplicates).
Generalize string literal creation to handle data with NUL characters and to properly support CHARACTER of KIND=2 and KIND=4. This allows the creation of ASCIIZ strings (needed for Fortran runtime support functions requiring C style strings).
1 parent 9e6685a commit 2fe26ba

File tree

2 files changed

+17
-4
lines changed

2 files changed

+17
-4
lines changed

flang/lib/Lower/ConvertExpr.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -710,8 +710,19 @@ class ExprLowering {
710710
{len}, fir::CharacterType::get(builder.getContext(), KIND));
711711
auto consLit = [&]() -> fir::StringLitOp {
712712
auto context = builder.getContext();
713-
auto strAttr =
714-
mlir::StringAttr::get((const char *)value.c_str(), context);
713+
mlir::Attribute strAttr;
714+
if constexpr (std::is_same_v<std::decay_t<decltype(value)>,
715+
std::string>) {
716+
strAttr = mlir::StringAttr::get(value, context);
717+
} else {
718+
using ET = typename std::decay_t<decltype(value)>::value_type;
719+
std::int64_t size = static_cast<std::int64_t>(value.size());
720+
auto shape = mlir::VectorType::get(
721+
llvm::ArrayRef<std::int64_t>{size},
722+
mlir::IntegerType::get(sizeof(ET) * 8, builder.getContext()));
723+
strAttr = mlir::DenseElementsAttr::get(
724+
shape, llvm::ArrayRef<ET>{value.data(), value.size()});
725+
}
715726
auto valTag = mlir::Identifier::get(fir::StringLitOp::value(), context);
716727
mlir::NamedAttribute dataAttr(valTag, strAttr);
717728
auto sizeTag = mlir::Identifier::get(fir::StringLitOp::size(), context);
@@ -1604,6 +1615,7 @@ fir::ExtendedValue Fortran::lower::createSomeExtendedAddress(
16041615
fir::ExtendedValue Fortran::lower::createStringLiteral(
16051616
mlir::Location loc, Fortran::lower::AbstractConverter &converter,
16061617
llvm::StringRef str, uint64_t len) {
1618+
assert(str.size() == len);
16071619
Fortran::lower::SymMap unused1;
16081620
Fortran::lower::ExpressionContext unused2;
16091621
return ExprLowering{loc, converter, unused1, unused2}.genStringLit(str, len);

flang/lib/Lower/IO.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -432,9 +432,10 @@ locationToFilename(Fortran::lower::AbstractConverter &converter,
432432
mlir::Location loc, mlir::Type toType) {
433433
auto &builder = converter.getFirOpBuilder();
434434
if (auto flc = loc.dyn_cast<mlir::FileLineColLoc>()) {
435-
auto fn = flc.getFilename();
435+
// must be encoded as asciiz, C string
436+
auto fn = flc.getFilename().str() + '\0';
436437
auto addr =
437-
fir::getBase(createStringLiteral(loc, converter, fn.data(), fn.size()));
438+
fir::getBase(createStringLiteral(loc, converter, fn, fn.size()));
438439
return builder.createConvert(loc, toType, addr);
439440
}
440441
mlir::Value null =

0 commit comments

Comments
 (0)