Skip to content

Conversation

klausler
Copy link
Contributor

We don't emit source file names or line numbers for error messages at EOF. Detect these and handle them a little better, pointing at the newline at the end of the last source line instead.

We don't emit source file names or line numbers for error messages
at EOF.  Detect these and handle them a little better, pointing at
the newline at the end of the last source line instead.
@llvmbot llvmbot added flang Flang issues not falling into any other category flang:parser labels Sep 30, 2025
@llvmbot
Copy link
Member

llvmbot commented Sep 30, 2025

@llvm/pr-subscribers-flang-parser

Author: Peter Klausler (klausler)

Changes

We don't emit source file names or line numbers for error messages at EOF. Detect these and handle them a little better, pointing at the newline at the end of the last source line instead.


Full diff: https://github.com/llvm/llvm-project/pull/161391.diff

4 Files Affected:

  • (modified) flang/include/flang/Parser/message.h (+2)
  • (modified) flang/lib/Parser/basic-parsers.h (+1-1)
  • (modified) flang/lib/Parser/message.cpp (+18-1)
  • (added) flang/test/Parser/recovery08.f90 (+11)
diff --git a/flang/include/flang/Parser/message.h b/flang/include/flang/Parser/message.h
index 7da9e12999db1..224263e4be860 100644
--- a/flang/include/flang/Parser/message.h
+++ b/flang/include/flang/Parser/message.h
@@ -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};
diff --git a/flang/lib/Parser/basic-parsers.h b/flang/lib/Parser/basic-parsers.h
index 7e69d41debfcd..46d5168c80fe7 100644
--- a/flang/lib/Parser/basic-parsers.h
+++ b/flang/lib/Parser/basic-parsers.h
@@ -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;
   }
 };
diff --git a/flang/lib/Parser/message.cpp b/flang/lib/Parser/message.cpp
index 2a8101dd0b810..2c4f930c0b088 100644
--- a/flang/lib/Parser/message.cpp
+++ b/flang/lib/Parser/message.cpp
@@ -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) {
@@ -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_);
diff --git a/flang/test/Parser/recovery08.f90 b/flang/test/Parser/recovery08.f90
new file mode 100644
index 0000000000000..978e42bab9344
--- /dev/null
+++ b/flang/test/Parser/recovery08.f90
@@ -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

@klausler klausler merged commit 8025302 into llvm:main Sep 30, 2025
12 checks passed
@klausler klausler deleted the bug286 branch September 30, 2025 17:37
@akuhlens
Copy link
Contributor

LGTM

mahesh-attarde pushed a commit to mahesh-attarde/llvm-project that referenced this pull request Oct 3, 2025
…61391)

We don't emit source file names or line numbers for error messages at
EOF. Detect these and handle them a little better, pointing at the
newline at the end of the last source line instead.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:parser flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants