[flang-commits] [flang] c105d9b - [flang] Admit trailing blanks when checking I/O specifiers
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Fri Jul 22 16:21:40 PDT 2022
Author: Peter Klausler
Date: 2022-07-22T16:21:32-07:00
New Revision: c105d9b3d638cf426c39216f64ae2e48759daee4
URL: https://github.com/llvm/llvm-project/commit/c105d9b3d638cf426c39216f64ae2e48759daee4
DIFF: https://github.com/llvm/llvm-project/commit/c105d9b3d638cf426c39216f64ae2e48759daee4.diff
LOG: [flang] Admit trailing blanks when checking I/O specifiers
Fortran specifically allows character-valued I/O specifiers
to have trailing blanks, e.g. OPEN(666,STATUS='SCRATCH ').
The runtime I/O library already handles them, but the I/O
static checks in semantics do not.
Differential Revision: https://reviews.llvm.org/D130381
Added:
Modified:
flang/lib/Semantics/check-io.cpp
flang/test/Semantics/io02.f90
Removed:
################################################################################
diff --git a/flang/lib/Semantics/check-io.cpp b/flang/lib/Semantics/check-io.cpp
index 01392eeb98604..7e9f9414ac8e1 100644
--- a/flang/lib/Semantics/check-io.cpp
+++ b/flang/lib/Semantics/check-io.cpp
@@ -97,6 +97,14 @@ void IoChecker::Enter(const parser::ConnectSpec &spec) {
}
}
+// Ignore trailing spaces (12.5.6.2 p1) and convert to upper case
+static std::string Normalize(const std::string &value) {
+ auto upper{parser::ToUpperCaseLetters(value)};
+ std::size_t lastNonBlank{upper.find_last_not_of(" ")};
+ upper.resize(lastNonBlank == std::string::npos ? 0 : lastNonBlank + 1);
+ return upper;
+}
+
void IoChecker::Enter(const parser::ConnectSpec::CharExpr &spec) {
IoSpecKind specKind{};
using ParseKind = parser::ConnectSpec::CharExpr::Kind;
@@ -150,7 +158,7 @@ void IoChecker::Enter(const parser::ConnectSpec::CharExpr &spec) {
SetSpecifier(specKind);
if (const std::optional<std::string> charConst{GetConstExpr<std::string>(
std::get<parser::ScalarDefaultCharExpr>(spec.t))}) {
- std::string s{parser::ToUpperCaseLetters(*charConst)};
+ std::string s{Normalize(*charConst)};
if (specKind == IoSpecKind::Access) {
flags_.set(Flag::KnownAccess);
flags_.set(Flag::AccessDirect, s == "DIRECT");
@@ -484,8 +492,7 @@ void IoChecker::Enter(const parser::IoControlSpec::Asynchronous &spec) {
SetSpecifier(IoSpecKind::Asynchronous);
if (const std::optional<std::string> charConst{
GetConstExpr<std::string>(spec)}) {
- flags_.set(
- Flag::AsynchronousYes, parser::ToUpperCaseLetters(*charConst) == "YES");
+ flags_.set(Flag::AsynchronousYes, Normalize(*charConst) == "YES");
CheckStringValue(IoSpecKind::Asynchronous, *charConst,
parser::FindSourceLocation(spec)); // C1223
}
@@ -521,8 +528,7 @@ void IoChecker::Enter(const parser::IoControlSpec::CharExpr &spec) {
if (const std::optional<std::string> charConst{GetConstExpr<std::string>(
std::get<parser::ScalarDefaultCharExpr>(spec.t))}) {
if (specKind == IoSpecKind::Advance) {
- flags_.set(
- Flag::AdvanceYes, parser::ToUpperCaseLetters(*charConst) == "YES");
+ flags_.set(Flag::AdvanceYes, Normalize(*charConst) == "YES");
}
CheckStringValue(specKind, *charConst, parser::FindSourceLocation(spec));
}
@@ -601,7 +607,7 @@ void IoChecker::Enter(const parser::StatusExpr &spec) {
if (const std::optional<std::string> charConst{
GetConstExpr<std::string>(spec)}) {
// Status values for Open and Close are
diff erent.
- std::string s{parser::ToUpperCaseLetters(*charConst)};
+ std::string s{Normalize(*charConst)};
if (stmt_ == IoStmtKind::Open) {
flags_.set(Flag::KnownStatus);
flags_.set(Flag::StatusNew, s == "NEW");
@@ -868,7 +874,7 @@ void IoChecker::CheckStringValue(IoSpecKind specKind, const std::string &value,
{IoSpecKind::Convert, {"BIG_ENDIAN", "LITTLE_ENDIAN", "NATIVE"}},
{IoSpecKind::Dispose, {"DELETE", "KEEP"}},
};
- auto upper{parser::ToUpperCaseLetters(value)};
+ auto upper{Normalize(value)};
if (specValues.at(specKind).count(upper) == 0) {
if (specKind == IoSpecKind::Access && upper == "APPEND") {
if (context_.languageFeatures().ShouldWarn(
diff --git a/flang/test/Semantics/io02.f90 b/flang/test/Semantics/io02.f90
index 40be023828c48..7571aac659a67 100644
--- a/flang/test/Semantics/io02.f90
+++ b/flang/test/Semantics/io02.f90
@@ -29,6 +29,9 @@
!ERROR: Invalid STATUS value 'old'
close(status='old', unit=17)
+ !Ok: trailing spaces ignored
+ close(status='keep ', unit=17)
+
!ERROR: IOSTAT variable 'const_stat' must be definable
close(14, iostat=const_stat)
More information about the flang-commits
mailing list