Index: flang/lib/Parser/basic-parsers.h =================================================================== --- flang/lib/Parser/basic-parsers.h +++ flang/lib/Parser/basic-parsers.h @@ -208,26 +208,31 @@ constexpr WithMessageParser(MessageFixedText t, PA p) : text_{t}, parser_{p} {} std::optional Parse(ParseState &state) const { + if (state.deferMessages()) { // fast path + std::optional result{parser_.Parse(state)}; + if (!result) { + state.set_anyDeferredMessages(); + } + return result; + } Messages messages{std::move(state.messages())}; - ParseState backtrack{state}; + bool hadAnyTokenMatched{state.anyTokenMatched()}; state.set_anyTokenMatched(false); std::optional result{parser_.Parse(state)}; bool emitMessage{false}; if (result) { messages.Annex(std::move(state.messages())); - if (backtrack.anyTokenMatched()) { + if (hadAnyTokenMatched) { state.set_anyTokenMatched(); } } else if (state.anyTokenMatched()) { emitMessage = state.messages().empty(); messages.Annex(std::move(state.messages())); - backtrack.set_anyTokenMatched(); - if (state.anyDeferredMessages()) { - backtrack.set_anyDeferredMessages(true); - } - state = std::move(backtrack); } else { emitMessage = true; + if (hadAnyTokenMatched) { + state.set_anyTokenMatched(); + } } state.messages() = std::move(messages); if (emitMessage) { @@ -351,7 +356,7 @@ using resultType = typename PA::resultType; static_assert(std::is_same_v); constexpr RecoveryParser(const RecoveryParser &) = default; - constexpr RecoveryParser(PA pa, PB pb) : pa_{pa}, pb3_{pb} {} + constexpr RecoveryParser(PA pa, PB pb) : pa_{pa}, pb_{pb} {} std::optional Parse(ParseState &state) const { bool originallyDeferred{state.deferMessages()}; ParseState backtrack{state}; @@ -379,7 +384,7 @@ bool anyTokenMatched{state.anyTokenMatched()}; state = std::move(backtrack); state.set_deferMessages(true); - std::optional bx{pb3_.Parse(state)}; + std::optional bx{pb_.Parse(state)}; state.messages() = std::move(messages); state.set_deferMessages(originallyDeferred); if (anyTokenMatched) { @@ -398,7 +403,7 @@ private: const PA pa_; - const PB pb3_; + const PB pb_; }; template Index: flang/test/Driver/color-diagnostics-parse.f90 =================================================================== --- flang/test/Driver/color-diagnostics-parse.f90 +++ flang/test/Driver/color-diagnostics-parse.f90 @@ -11,9 +11,9 @@ ! RUN: | FileCheck %s --check-prefix=CHECK_CD ! RUN: not %flang_fc1 %s 2>&1 | FileCheck %s --check-prefix=CHECK_NCD -! CHECK_CD: {{.*}}[0;1;31merror: {{.*}}[0mexpected '(' +! CHECK_CD: {{.*}}[0;1;31merror: {{.*}}[0mexpected end of statement -! CHECK_NCD: error: expected '(' +! CHECK_NCD: error: expected end of statement program m integer :: i = Index: flang/test/Parser/doubled-comma.f90 =================================================================== --- /dev/null +++ flang/test/Parser/doubled-comma.f90 @@ -0,0 +1,4 @@ +! RUN: not %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s +! CHECK: 3:13: error: expected end of statement +common/blk/a,,b +end Index: flang/test/Semantics/error_stop1a.f90 =================================================================== --- flang/test/Semantics/error_stop1a.f90 +++ flang/test/Semantics/error_stop1a.f90 @@ -43,47 +43,47 @@ !___ non-standard-conforming statements _________________________ ! unknown stop-code - !ERROR: expected execution part construct + !ERROR: expected end of statement error stop code=int_code ! missing 'quiet=' - !ERROR: expected execution part construct + !ERROR: expected end of statement error stop int_code, bool ! incorrect spelling for 'quiet=' - !ERROR: expected execution part construct + !ERROR: expected end of statement error stop int_code, quiets=bool ! missing scalar-logical-expr for quiet= - !ERROR: expected execution part construct + !ERROR: expected end of statement error stop int_code, quiet ! superfluous stop-code - !ERROR: expected execution part construct + !ERROR: expected end of statement error stop int_code, char_code ! repeated quiet= - !ERROR: expected execution part construct + !ERROR: expected end of statement error stop int_code, quiet=bool, quiet=.true. ! superfluous stop-code - !ERROR: expected execution part construct + !ERROR: expected end of statement error stop int_code, char_code, quiet=bool ! superfluous integer - !ERROR: expected execution part construct + !ERROR: expected end of statement error stop int_code, quiet=bool, 5 ! quiet= appears without stop-code - !ERROR: expected execution part construct + !ERROR: expected end of statement error stop quiet=bool ! incorrect syntax - !ERROR: expected execution part construct + !ERROR: expected end of statement error stop () ! incorrect syntax - !ERROR: expected execution part construct + !ERROR: expected end of statement error stop (2, quiet=.true.) end program test_error_stop Index: flang/test/Semantics/synchronization01a.f90 =================================================================== --- flang/test/Semantics/synchronization01a.f90 +++ flang/test/Semantics/synchronization01a.f90 @@ -20,29 +20,29 @@ !______ invalid sync-stat-lists: invalid stat= ____________ - !ERROR: expected execution part construct + !ERROR: expected end of statement sync all(status=sync_status) ! Invalid sync-stat-list: missing stat-variable - !ERROR: expected execution part construct + !ERROR: expected end of statement sync all(stat) ! Invalid sync-stat-list: missing 'stat=' - !ERROR: expected execution part construct + !ERROR: expected end of statement sync all(sync_status) !______ invalid sync-stat-lists: invalid errmsg= ____________ ! Invalid errmsg-variable keyword - !ERROR: expected execution part construct + !ERROR: expected end of statement sync all(errormsg=error_message) ! Invalid sync-stat-list: missing 'errmsg=' - !ERROR: expected execution part construct + !ERROR: expected end of statement sync all(error_message) ! Invalid sync-stat-list: missing errmsg-variable - !ERROR: expected execution part construct + !ERROR: expected end of statement sync all(errmsg) end program test_sync_all Index: flang/test/Semantics/synchronization03a.f90 =================================================================== --- flang/test/Semantics/synchronization03a.f90 +++ flang/test/Semantics/synchronization03a.f90 @@ -20,29 +20,29 @@ !______ invalid sync-stat-lists: invalid stat= ____________ - !ERROR: expected execution part construct + !ERROR: expected end of statement sync memory(status=sync_status) ! Invalid sync-stat-list: missing stat-variable - !ERROR: expected execution part construct + !ERROR: expected end of statement sync memory(stat) ! Invalid sync-stat-list: missing 'stat=' - !ERROR: expected execution part construct + !ERROR: expected end of statement sync memory(sync_status) !______ invalid sync-stat-lists: invalid errmsg= ____________ ! Invalid errmsg-variable keyword - !ERROR: expected execution part construct + !ERROR: expected end of statement sync memory(errormsg=error_message) ! Invalid sync-stat-list: missing 'errmsg=' - !ERROR: expected execution part construct + !ERROR: expected end of statement sync memory(error_message) ! Invalid sync-stat-list: missing errmsg-variable - !ERROR: expected execution part construct + !ERROR: expected end of statement sync memory(errmsg) end program test_sync_memory