From 04a147987a6bde657bcdd505e651b7580cc60a2e Mon Sep 17 00:00:00 2001 From: peter klausler Date: Thu, 12 Nov 2020 11:57:23 -0800 Subject: [PATCH] [flang] Include source information in an invalid file-unit-number message An io-unit that is an internal-file-variable is syntactically identical to a file-unit-number expression that is a variable reference. An ambiguous unit is initially parsed as an internal-file-variable. If semantic analysis determines that the unit is not of character type, it is rewritten as an internal-file-variable. This modification must retain source coordinate information. Differential revision: https://reviews.llvm.org/D91375 --- flang/lib/Semantics/rewrite-parse-tree.cpp | 4 ++++ flang/test/Semantics/io04.f90 | 3 +++ 2 files changed, 7 insertions(+) diff --git a/flang/lib/Semantics/rewrite-parse-tree.cpp b/flang/lib/Semantics/rewrite-parse-tree.cpp index 706e28c..2b92647 100644 --- a/flang/lib/Semantics/rewrite-parse-tree.cpp +++ b/flang/lib/Semantics/rewrite-parse-tree.cpp @@ -110,6 +110,8 @@ bool RewriteMutator::Pre(parser::ExecutionPart &x) { return true; } +// Convert a syntactically ambiguous io-unit internal-file-variable to a +// file-unit-number. void RewriteMutator::Post(parser::IoUnit &x) { if (auto *var{std::get_if(&x.u)}) { const parser::Name &last{parser::GetLastName(*var)}; @@ -118,11 +120,13 @@ void RewriteMutator::Post(parser::IoUnit &x) { // If the Variable is not known to be character (any kind), transform // the I/O unit in situ to a FileUnitNumber so that automatic expression // constraint checking will be applied. + auto source{var->GetSource()}; auto expr{std::visit( [](auto &&indirection) { return parser::Expr{std::move(indirection)}; }, std::move(var->u))}; + expr.source = source; x.u = parser::FileUnitNumber{ parser::ScalarIntExpr{parser::IntExpr{std::move(expr)}}}; } diff --git a/flang/test/Semantics/io04.f90 b/flang/test/Semantics/io04.f90 index 6be2604..8beb446 100644 --- a/flang/test/Semantics/io04.f90 +++ b/flang/test/Semantics/io04.f90 @@ -87,6 +87,9 @@ !ERROR: If UNIT=* appears, REC must not appear write(*, rec=13) 'Ok' + !ERROR: Must have INTEGER type, but is REAL(4) + write(unit, *) 'Ok' + !ERROR: If ADVANCE appears, UNIT=internal-file must not appear write(internal_file, advance='yes', fmt=1) 'Ok' -- 2.7.4