Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions flang/include/flang/Parser/message.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ class MessageFixedText {
return severity_ == Severity::Error || severity_ == Severity::Todo;
}

static const MessageFixedText endOfFileMessage; // "end of file"_err_en_US

private:
CharBlock text_;
Severity severity_{Severity::None};
Expand Down
2 changes: 1 addition & 1 deletion flang/lib/Parser/basic-parsers.h
Original file line number Diff line number Diff line change
Expand Up @@ -828,7 +828,7 @@ struct NextCh {
if (std::optional<const char *> result{state.GetNextChar()}) {
return result;
}
state.Say("end of file"_err_en_US);
state.Say(MessageFixedText::endOfFileMessage);
return std::nullopt;
}
};
Expand Down
19 changes: 18 additions & 1 deletion flang/lib/Parser/message.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@

namespace Fortran::parser {

// The nextCh parser emits this, and Message::GetProvenanceRange() looks for it.
const MessageFixedText MessageFixedText::endOfFileMessage{
"end of file"_err_en_US};

llvm::raw_ostream &operator<<(llvm::raw_ostream &o, const MessageFixedText &t) {
std::size_t n{t.text().size()};
for (std::size_t j{0}; j < n; ++j) {
Expand Down Expand Up @@ -232,7 +236,20 @@ std::optional<ProvenanceRange> Message::GetProvenanceRange(
const AllCookedSources &allCooked) const {
return common::visit(
common::visitors{
[&](CharBlock cb) { return allCooked.GetProvenanceRange(cb); },
[&](CharBlock cb) -> std::optional<ProvenanceRange> {
if (auto pr{allCooked.GetProvenanceRange(cb)}) {
return pr;
} else if (const auto *fixed{std::get_if<MessageFixedText>(&text_)};
fixed &&
fixed->text() == MessageFixedText::endOfFileMessage.text() &&
cb.begin() && cb.size() == 1) {
// Failure from "nextCh" due to reaching EOF. Back up one byte
// to the terminal newline so that the output looks better.
return allCooked.GetProvenanceRange(CharBlock{cb.begin() - 1, 1});
} else {
return std::nullopt;
}
},
[](const ProvenanceRange &pr) { return std::make_optional(pr); },
},
location_);
Expand Down
11 changes: 11 additions & 0 deletions flang/test/Parser/recovery08.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
! RUN: not %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s
! CHECK: error: end of file
! CHECK: ^
! CHECK: in the context: END PROGRAM statement
! CHECK: in the context: main program

integer :: i

! Add empty lines for emphasis

i = 5