From c9b31dae56f155ed08cc855dffe7eae2ea8cd30d Mon Sep 17 00:00:00 2001 From: Peter Klausler Date: Thu, 29 Jun 2023 15:19:23 -0700 Subject: [PATCH] [flang][runtime] Allow OPEN(n,ENCODING=) to change the encoding OPEN statements can be used to change some, but not all, attributes of units that have already been opened. The I/O runtime library wasn't allowing ENCODING= to be changed. Every other Fortran compiler permits this usage, and it's safe and useful, so allow it. (Otherwise there's no good way to ensure that the preconnected unit 6 is in UTF-8 mode.) Differential Revision: https://reviews.llvm.org/D154379 --- flang/docs/Extensions.md | 4 ++++ flang/runtime/io-api.cpp | 13 ++++--------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md index eb885b3aaeb7..d3cb2f142c54 100644 --- a/flang/docs/Extensions.md +++ b/flang/docs/Extensions.md @@ -592,3 +592,7 @@ end module * `EXTENDS_TYPE_OF()` returns `.TRUE.` if both of its arguments have the same type, a case that is technically implementation-defined. + +* `ENCODING=` is not in the list of changeable modes on an I/O unit, + but every Fortran compiler allows the encoding to be changed on an + open unit. diff --git a/flang/runtime/io-api.cpp b/flang/runtime/io-api.cpp index 4d569f898ea8..fe58bbc75f83 100644 --- a/flang/runtime/io-api.cpp +++ b/flang/runtime/io-api.cpp @@ -927,25 +927,20 @@ bool IONAME(SetEncoding)( io.GetIoErrorHandler().Crash( "SetEncoding() called after GetNewUnit() for an OPEN statement"); } - bool isUTF8{false}; + // Allow the encoding to be changed on an open unit -- it's + // useful and safe. static const char *keywords[]{"UTF-8", "DEFAULT", nullptr}; switch (IdentifyValue(keyword, length, keywords)) { case 0: - isUTF8 = true; + open->unit().isUTF8 = true; break; case 1: - isUTF8 = false; + open->unit().isUTF8 = false; break; default: open->SignalError(IostatErrorInKeyword, "Invalid ENCODING='%.*s'", static_cast(length), keyword); } - if (isUTF8 != open->unit().isUTF8) { - if (open->wasExtant()) { - open->SignalError("ENCODING= may not be changed on an open unit"); - } - open->unit().isUTF8 = isUTF8; - } return true; }