Skip to content

Commit d1ea605

Browse files
authored
[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.
1 parent 7463b46 commit d1ea605

File tree

5 files changed

+27
-5
lines changed

5 files changed

+27
-5
lines changed

flang/lib/Frontend/FrontendAction.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,19 @@ bool FrontendAction::reportFatalErrors(const char (&message)[N]) {
232232
instance->getAllCookedSources());
233233
return true;
234234
}
235+
if (instance->getParsing().parseTree().has_value() &&
236+
!instance->getParsing().consumedWholeFile()) {
237+
// Parsing failed without error.
238+
const unsigned diagID = instance->getDiagnostics().getCustomDiagID(
239+
clang::DiagnosticsEngine::Error, message);
240+
instance->getDiagnostics().Report(diagID) << getCurrentFileOrBufferName();
241+
instance->getParsing().messages().Emit(llvm::errs(),
242+
instance->getAllCookedSources());
243+
instance->getParsing().EmitMessage(
244+
llvm::errs(), instance->getParsing().finalRestingPlace(),
245+
"parser FAIL (final position)", "error: ", llvm::raw_ostream::RED);
246+
return true;
247+
}
235248
return false;
236249
}
237250

flang/lib/Frontend/FrontendActions.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -566,9 +566,11 @@ void DebugMeasureParseTreeAction::executeAction() {
566566
// Parse. In case of failure, report and return.
567567
ci.getParsing().Parse(llvm::outs());
568568

569-
if (!ci.getParsing().messages().empty() &&
570-
(ci.getInvocation().getWarnAsErr() ||
571-
ci.getParsing().messages().AnyFatalError())) {
569+
if ((ci.getParsing().parseTree().has_value() &&
570+
!ci.getParsing().consumedWholeFile()) ||
571+
(!ci.getParsing().messages().empty() &&
572+
(ci.getInvocation().getWarnAsErr() ||
573+
ci.getParsing().messages().AnyFatalError()))) {
572574
unsigned diagID = ci.getDiagnostics().getCustomDiagID(
573575
clang::DiagnosticsEngine::Error, "Could not parse %0");
574576
ci.getDiagnostics().Report(diagID) << getCurrentFileOrBufferName();

flang/test/Integration/debug-local-var-2.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,4 @@ function fn2(a2, b2, c2) result (res2)
107107
end function
108108
end program
109109

110-
LINEONLY-NOT: DILocalVariable
110+
! LINEONLY-NOT: DILocalVariable

flang/test/Parser/at-process.f

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
! RUN: %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s
1+
! RUN: not %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s
22

33
! Test ignoring @PROCESS directive in fixed source form
44

@@ -18,3 +18,5 @@ subroutine f()
1818

1919
!CHECK: Character in fixed-form label field must be a digit
2020
@precoss
21+
22+
!CHECK: at-process.f:14:1: error: parser FAIL (final position)

flang/test/Parser/unparseable.f90

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
! RUN: not %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s
2+
! CHECK: unparseable.f90:5:1: error: parser FAIL (final position)
3+
module m
4+
end
5+
select type (barf)

0 commit comments

Comments
 (0)