diff --git a/flang/runtime/connection.h b/flang/runtime/connection.h --- a/flang/runtime/connection.h +++ b/flang/runtime/connection.h @@ -34,6 +34,13 @@ // Formatted stream files are viewed as having records, at least on input return access != Access::Stream || !isUnformatted.value_or(true); } + + template constexpr bool useUTF8() const { + // For wide CHARACTER kinds, always use UTF-8 for formatted I/O. + // For single-byte CHARACTER, encode characters >= 0x80 with + // UTF-8 iff the mode is set. + return sizeof(CHAR) > 1 || isUTF8; + } }; struct ConnectionState : public ConnectionAttributes { diff --git a/flang/runtime/edit-output.cpp b/flang/runtime/edit-output.cpp --- a/flang/runtime/edit-output.cpp +++ b/flang/runtime/edit-output.cpp @@ -506,7 +506,7 @@ // Undelimited list-directed output ok = ok && list.EmitLeadingSpaceOrAdvance(io, length > 0 ? 1 : 0, true); std::size_t put{0}; - std::size_t oneIfUTF8{connection.isUTF8 ? 1 : length}; + std::size_t oneIfUTF8{connection.useUTF8() ? 1 : length}; while (ok && put < length) { if (std::size_t chunk{std::min( std::min(length - put, oneIfUTF8), diff --git a/flang/runtime/io-stmt.cpp b/flang/runtime/io-stmt.cpp --- a/flang/runtime/io-stmt.cpp +++ b/flang/runtime/io-stmt.cpp @@ -477,7 +477,7 @@ // Don't allow sign extension using UnsignedChar = std::make_unsigned_t; const UnsignedChar *data{reinterpret_cast(data0)}; - if (GetConnectionState().isUTF8) { + if (GetConnectionState().useUTF8()) { char buffer[256]; std::size_t at{0}; while (chars-- > 0) {