Skip to content

Commit a70ffe7

Browse files
authored
[flang] Support "PRINT namelistname" (#112024)
Nearly every Fortran compiler supports "PRINT namelistname" as a synonym for "WRITE (*, NML=namelistname)". Implement this extension via parse tree rewriting. Fixes #111738.
1 parent 5a9d684 commit a70ffe7

File tree

4 files changed

+37
-2
lines changed

4 files changed

+37
-2
lines changed

flang/docs/Extensions.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,8 @@ end
389389
* A local data object may appear in a specification expression, even
390390
when it is not a dummy argument or in COMMON, so long as it is
391391
has the SAVE attribute and was initialized.
392+
* `PRINT namelistname` is accepted and interpreted as
393+
`WRITE(*,NML=namelistname)`, a near-universal extension.
392394

393395
### Extensions supported when enabled by options
394396

flang/include/flang/Common/Fortran-features.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines,
5353
NonBindCInteroperability, CudaManaged, CudaUnified,
5454
PolymorphicActualAllocatableOrPointerToMonomorphicDummy, RelaxedPureDummy,
5555
UndefinableAsynchronousOrVolatileActual, AutomaticInMainProgram, PrintCptr,
56-
SavedLocalInSpecExpr)
56+
SavedLocalInSpecExpr, PrintNamelist)
5757

5858
// Portability and suspicious usage warnings
5959
ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable,

flang/lib/Semantics/rewrite-parse-tree.cpp

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ using namespace parser::literals;
3232
class RewriteMutator {
3333
public:
3434
RewriteMutator(SemanticsContext &context)
35-
: errorOnUnresolvedName_{!context.AnyFatalError()},
35+
: context_{context}, errorOnUnresolvedName_{!context.AnyFatalError()},
3636
messages_{context.messages()} {}
3737

3838
// Default action for a parse tree node is to visit children.
@@ -42,6 +42,7 @@ class RewriteMutator {
4242
void Post(parser::Name &);
4343
void Post(parser::SpecificationPart &);
4444
bool Pre(parser::ExecutionPart &);
45+
bool Pre(parser::ActionStmt &);
4546
void Post(parser::ReadStmt &);
4647
void Post(parser::WriteStmt &);
4748

@@ -66,6 +67,7 @@ class RewriteMutator {
6667
private:
6768
using stmtFuncType =
6869
parser::Statement<common::Indirection<parser::StmtFunctionStmt>>;
70+
SemanticsContext &context_;
6971
bool errorOnUnresolvedName_{true};
7072
parser::Messages &messages_;
7173
std::list<stmtFuncType> stmtFuncsToConvert_;
@@ -130,6 +132,29 @@ bool RewriteMutator::Pre(parser::ExecutionPart &x) {
130132
return true;
131133
}
132134

135+
// Rewrite PRINT NML -> WRITE(*,NML=NML)
136+
bool RewriteMutator::Pre(parser::ActionStmt &x) {
137+
if (auto *print{std::get_if<common::Indirection<parser::PrintStmt>>(&x.u)};
138+
print &&
139+
std::get<std::list<parser::OutputItem>>(print->value().t).empty()) {
140+
auto &format{std::get<parser::Format>(print->value().t)};
141+
if (std::holds_alternative<parser::Expr>(format.u)) {
142+
if (auto *name{parser::Unwrap<parser::Name>(format)}; name &&
143+
name->symbol && name->symbol->GetUltimate().has<NamelistDetails>() &&
144+
context_.IsEnabled(common::LanguageFeature::PrintNamelist)) {
145+
context_.Warn(common::LanguageFeature::PrintNamelist, name->source,
146+
"nonstandard: namelist in PRINT statement"_port_en_US);
147+
std::list<parser::IoControlSpec> controls;
148+
controls.emplace_back(std::move(*name));
149+
x.u = common::Indirection<parser::WriteStmt>::Make(
150+
parser::IoUnit{parser::Star{}}, std::optional<parser::Format>{},
151+
std::move(controls), std::list<parser::OutputItem>{});
152+
}
153+
}
154+
}
155+
return true;
156+
}
157+
133158
// When a namelist group name appears (without NML=) in a READ or WRITE
134159
// statement in such a way that it can be misparsed as a format expression,
135160
// rewrite the I/O statement's parse tree node as if the namelist group

flang/test/Semantics/rewrite02.f90

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
!RUN: %flang_fc1 -fdebug-unparse -pedantic %s 2>&1 | FileCheck %s
2+
!Test rewrite of "PRINT namelistname" into "WRITE(*,NML=namelistname)"
3+
!CHECK: nonstandard: namelist in PRINT statement
4+
namelist /nml/x
5+
x = 123.
6+
!CHECK: WRITE (*, NML=nml)
7+
print nml
8+
end

0 commit comments

Comments
 (0)