[flang] Detect and report parsing failure (#121349)

The flang-new driver doesn't check for the case of the parser failing to
consume the entire input file. This is of course never an ideal outcome,
and usually signals a need to improve error recovery, but it is better
for the compiler to admit failure rather than to silently proceed with
compilation of what may well be an incomplete parse tree.
This commit is contained in:
Peter Klausler 2025-01-08 13:12:58 -08:00 committed by GitHub
parent 7463b46a34
commit d1ea605ecd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 27 additions and 5 deletions

View File

@ -232,6 +232,19 @@ bool FrontendAction::reportFatalErrors(const char (&message)[N]) {
instance->getAllCookedSources());
return true;
}
if (instance->getParsing().parseTree().has_value() &&
!instance->getParsing().consumedWholeFile()) {
// Parsing failed without error.
const unsigned diagID = instance->getDiagnostics().getCustomDiagID(
clang::DiagnosticsEngine::Error, message);
instance->getDiagnostics().Report(diagID) << getCurrentFileOrBufferName();
instance->getParsing().messages().Emit(llvm::errs(),
instance->getAllCookedSources());
instance->getParsing().EmitMessage(
llvm::errs(), instance->getParsing().finalRestingPlace(),
"parser FAIL (final position)", "error: ", llvm::raw_ostream::RED);
return true;
}
return false;
}

View File

@ -566,9 +566,11 @@ void DebugMeasureParseTreeAction::executeAction() {
// Parse. In case of failure, report and return.
ci.getParsing().Parse(llvm::outs());
if (!ci.getParsing().messages().empty() &&
(ci.getInvocation().getWarnAsErr() ||
ci.getParsing().messages().AnyFatalError())) {
if ((ci.getParsing().parseTree().has_value() &&
!ci.getParsing().consumedWholeFile()) ||
(!ci.getParsing().messages().empty() &&
(ci.getInvocation().getWarnAsErr() ||
ci.getParsing().messages().AnyFatalError()))) {
unsigned diagID = ci.getDiagnostics().getCustomDiagID(
clang::DiagnosticsEngine::Error, "Could not parse %0");
ci.getDiagnostics().Report(diagID) << getCurrentFileOrBufferName();

View File

@ -107,4 +107,4 @@ contains
end function
end program
LINEONLY-NOT: DILocalVariable
! LINEONLY-NOT: DILocalVariable

View File

@ -1,4 +1,4 @@
! RUN: %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s
! RUN: not %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s
! Test ignoring @PROCESS directive in fixed source form
@ -18,3 +18,5 @@ c@process
!CHECK: Character in fixed-form label field must be a digit
@precoss
!CHECK: at-process.f:14:1: error: parser FAIL (final position)

View File

@ -0,0 +1,5 @@
! RUN: not %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s
! CHECK: unparseable.f90:5:1: error: parser FAIL (final position)
module m
end
select type (barf)