[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
This commit is contained in:
Peter Klausler 2023-06-29 15:19:23 -07:00
parent 2163e662c6
commit c9b31dae56
No known key found for this signature in database
2 changed files with 8 additions and 9 deletions

View File

@ -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.

View File

@ -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<int>(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;
}