[clang] [clang-repl] Address error recovery fixing infinite loop while parsing (PR #127569)

Anutosh Bhat via cfe-commits cfe-commits at lists.llvm.org
Wed Feb 11 01:15:35 PST 2026


https://github.com/anutosh491 updated https://github.com/llvm/llvm-project/pull/127569

>From 5bda5cb946e8056a43e487e66487632729d37aee Mon Sep 17 00:00:00 2001
From: anutosh491 <andersonbhat491 at gmail.com>
Date: Tue, 18 Feb 2025 11:23:30 +0530
Subject: [PATCH 1/4] Address error recovery fixing infinite loop while parsing

---
 clang/lib/Parse/ParseStmt.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index cd4504630f871..a044c8acab927 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -1253,7 +1253,7 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
 
   bool LastIsError = false;
   while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
-         Tok.isNot(tok::eof)) {
+         Tok.isNot(tok::eof) && Tok.isNot(tok::annot_repl_input_end)) {
     if (Tok.is(tok::annot_pragma_unused)) {
       HandlePragmaUnused();
       continue;

>From 51ab206b0859363fd5d6c30932bc01c7a551f687 Mon Sep 17 00:00:00 2001
From: anutosh491 <andersonbhat491 at gmail.com>
Date: Wed, 11 Feb 2026 13:34:05 +0530
Subject: [PATCH 2/4] Apply discussed change

---
 clang/include/clang/Parse/Parser.h        |  9 ++++++++
 clang/lib/Parse/ParseCXXInlineMethods.cpp | 16 +++++++-------
 clang/lib/Parse/ParseDecl.cpp             |  8 +++----
 clang/lib/Parse/ParseDeclCXX.cpp          |  8 +++----
 clang/lib/Parse/ParseExprCXX.cpp          |  2 +-
 clang/lib/Parse/ParseHLSL.cpp             |  2 +-
 clang/lib/Parse/ParseObjc.cpp             |  2 +-
 clang/lib/Parse/ParseOpenMP.cpp           |  2 +-
 clang/lib/Parse/ParsePragma.cpp           | 26 ++++++++++++++---------
 clang/lib/Parse/ParseStmt.cpp             |  2 +-
 clang/lib/Parse/Parser.cpp                |  2 +-
 11 files changed, 47 insertions(+), 32 deletions(-)

diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 5ae02e2b4e8ad..647ec8b0299ad 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -721,6 +721,15 @@ class Parser : public CodeCompletionHandler {
            Kind == tok::annot_repl_input_end;
   }
 
+  /// Determine if the given token marks the end of the current parsing unit.
+  /// In incremental (REPL) mode, this checks for annot_repl_input_end.
+  /// In normal compilation, this checks for EOF.
+  bool isAtInputEnd(const Token &T) const {
+    if (getLangOpts().IncrementalExtensions)
+      return T.is(tok::annot_repl_input_end);
+    return T.is(tok::eof);
+  }
+
   static void setTypeAnnotation(Token &Tok, TypeResult T) {
     assert((T.isInvalid() || T.get()) &&
            "produced a valid-but-null type annotation?");
diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp
index bc18881e89110..a83568be93056 100644
--- a/clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp
@@ -426,7 +426,7 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) {
         Actions.ActOnParamDefaultArgumentError(Param, EqualLoc,
                                                /*DefaultArg=*/nullptr);
       } else {
-        if (Tok.isNot(tok::eof) || Tok.getEofData() != Param) {
+        if (!isAtInputEnd(Tok) || Tok.getEofData() != Param) {
           // The last two tokens are the terminator and the saved value of
           // Tok; the last token in the default argument is the one before
           // those.
@@ -441,7 +441,7 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) {
 
       // There could be leftover tokens (e.g. because of an error).
       // Skip through until we reach the 'end of default argument' token.
-      while (Tok.isNot(tok::eof))
+      while (!isAtInputEnd(Tok))
         ConsumeAnyToken();
 
       if (Tok.is(tok::eof) && Tok.getEofData() == Param)
@@ -534,7 +534,7 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) {
                                        DynamicExceptionRanges, NoexceptExpr,
                                        ExceptionSpecTokens);
 
-    if (Tok.isNot(tok::eof) || Tok.getEofData() != LM.Method)
+    if (!isAtInputEnd(Tok) || Tok.getEofData() != LM.Method)
       Diag(Tok.getLocation(), diag::err_except_spec_unparsed);
 
     // Attach the exception-specification to the method.
@@ -547,7 +547,7 @@ void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) {
 
     // There could be leftover tokens (e.g. because of an error).
     // Skip through until we reach the original token position.
-    while (Tok.isNot(tok::eof))
+    while (!isAtInputEnd(Tok))
       ConsumeAnyToken();
 
     // Clean up the remaining EOF token.
@@ -604,7 +604,7 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) {
   Actions.ActOnStartOfFunctionDef(getCurScope(), LM.D);
 
   llvm::scope_exit _([&]() {
-    while (Tok.isNot(tok::eof))
+    while (!isAtInputEnd(Tok))
       ConsumeAnyToken();
 
     if (Tok.is(tok::eof) && Tok.getEofData() == LM.D)
@@ -691,7 +691,7 @@ void Parser::ParseLexedMemberInitializer(LateParsedMemberInitializer &MI) {
   Actions.ActOnFinishCXXInClassMemberInitializer(MI.Field, EqualLoc, Init);
 
   // The next token should be our artificial terminating EOF token.
-  if (Tok.isNot(tok::eof)) {
+  if (!isAtInputEnd(Tok)) {
     if (!Init.isInvalid()) {
       SourceLocation EndLoc = PP.getLocForEndOfToken(PrevTokLocation);
       if (!EndLoc.isValid())
@@ -701,7 +701,7 @@ void Parser::ParseLexedMemberInitializer(LateParsedMemberInitializer &MI) {
     }
 
     // Consume tokens until we hit the artificial EOF.
-    while (Tok.isNot(tok::eof))
+    while (!isAtInputEnd(Tok))
       ConsumeAnyToken();
   }
   // Make sure this is *our* artificial EOF token.
@@ -797,7 +797,7 @@ void Parser::ParseLexedAttribute(LateParsedAttribute &LA,
 
   // Due to a parsing error, we either went over the cached tokens or
   // there are still cached tokens left, so we skip the leftover tokens.
-  while (Tok.isNot(tok::eof))
+  while (!isAtInputEnd(Tok))
     ConsumeAnyToken();
 
   if (Tok.is(tok::eof) && Tok.getEofData() == AttrEnd.getEofData())
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index df9e3878bffc0..8bea74976e312 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -4832,7 +4832,7 @@ void Parser::ParseLexedCAttribute(LateParsedAttribute &LA, bool EnterScope,
 
   // Due to a parsing error, we either went over the cached tokens or
   // there are still cached tokens left, so we skip the leftover tokens.
-  while (Tok.isNot(tok::eof))
+  while (!isAtInputEnd(Tok))
     ConsumeAnyToken();
 
   // Consume the fake EOF token if it's there
@@ -4864,7 +4864,7 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
 
   // While we still have something to read, read the declarations in the struct.
   while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
-         Tok.isNot(tok::eof)) {
+         !isAtInputEnd(Tok)) {
     // Each iteration of this loop reads one struct-declaration.
 
     // Check for extraneous top-level semicolon.
@@ -8161,13 +8161,13 @@ TypeResult Parser::ParseTypeFromString(StringRef TypeStr, StringRef Context,
 
   // Check if we parsed the whole thing.
   if (Result.isUsable() &&
-      (Tok.isNot(tok::eof) || Tok.getEofData() != TypeStr.data())) {
+      (!isAtInputEnd(Tok) || Tok.getEofData() != TypeStr.data())) {
     Diag(Tok.getLocation(), diag::err_type_unparsed);
   }
 
   // There could be leftover tokens (e.g. because of an error).
   // Skip through until we reach the 'end of directive' token.
-  while (Tok.isNot(tok::eof))
+  while (!isAtInputEnd(Tok))
     ConsumeAnyToken();
 
   // Consume the end token.
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 9117a725843d9..749d13d7e81a0 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -229,7 +229,7 @@ void Parser::ParseInnerNamespace(const InnerNamespaceInfoList &InnerNSs,
                                  BalancedDelimiterTracker &Tracker) {
   if (index == InnerNSs.size()) {
     while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
-           Tok.isNot(tok::eof)) {
+           !isAtInputEnd(Tok)) {
       ParsedAttributes DeclAttrs(AttrFactory);
       MaybeParseCXX11Attributes(DeclAttrs);
       ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
@@ -428,7 +428,7 @@ Decl *Parser::ParseExportDeclaration() {
   T.consumeOpen();
 
   while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
-         Tok.isNot(tok::eof)) {
+         !isAtInputEnd(Tok)) {
     ParsedAttributes DeclAttrs(AttrFactory);
     MaybeParseCXX11Attributes(DeclAttrs);
     ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
@@ -3671,7 +3671,7 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
   if (TagDecl) {
     // While we still have something to read, read the member-declarations.
     while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
-           Tok.isNot(tok::eof)) {
+           !isAtInputEnd(Tok)) {
       // Each iteration of this loop reads one member-declaration.
       ParseCXXClassMemberDeclarationWithPragmas(
           CurAS, AccessAttrs, static_cast<DeclSpec::TST>(TagType), TagDecl);
@@ -4441,7 +4441,7 @@ bool Parser::ParseCXX11AttributeArgs(
   if (LO.CPlusPlus) {
     TentativeParsingAction TPA(*this);
     bool HasInvalidArgument = false;
-    while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::eof)) {
+    while (Tok.isNot(tok::r_paren) && !isAtInputEnd(Tok)) {
       if (Tok.isOneOf(tok::hash, tok::hashhash)) {
         Diag(Tok.getLocation(), diag::ext_invalid_attribute_argument)
             << PP.getSpelling(Tok);
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index 842b52375eb14..2d2d8e1dcac81 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -3698,7 +3698,7 @@ Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType,
 
   // Match the ')'.
   if (Result.isInvalid()) {
-    while (Tok.isNot(tok::eof))
+    while (!isAtInputEnd(Tok))
       ConsumeAnyToken();
     assert(Tok.getEofData() == AttrEnd.getEofData());
     ConsumeAnyToken();
diff --git a/clang/lib/Parse/ParseHLSL.cpp b/clang/lib/Parse/ParseHLSL.cpp
index c727ee3a1f1a6..a4a948ee10f9b 100644
--- a/clang/lib/Parse/ParseHLSL.cpp
+++ b/clang/lib/Parse/ParseHLSL.cpp
@@ -77,7 +77,7 @@ Decl *Parser::ParseHLSLBuffer(SourceLocation &DeclEnd,
                                             T.getOpenLocation());
   Actions.ProcessDeclAttributeList(Actions.CurScope, D, Attrs);
 
-  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
+  while (Tok.isNot(tok::r_brace) && !isAtInputEnd(Tok)) {
     // FIXME: support attribute on constants inside cbuffer/tbuffer.
     ParsedAttributes DeclAttrs(AttrFactory);
     ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);
diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp
index 0b9f113d9edc7..b59db1cb1f920 100644
--- a/clang/lib/Parse/ParseObjc.cpp
+++ b/clang/lib/Parse/ParseObjc.cpp
@@ -3324,7 +3324,7 @@ void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod) {
     // expensive isBeforeInTranslationUnit call.
     if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(),
                                                      OrigLoc))
-      while (Tok.getLocation() != OrigLoc && Tok.isNot(tok::eof))
+      while (Tok.getLocation() != OrigLoc && !isAtInputEnd(Tok))
         ConsumeAnyToken();
   }
   // Clean up the remaining EOF token, only if it's inserted by us. Otherwise
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index b41803d23cb25..08237e69524ff 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -1973,7 +1973,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
       CachedTokens Toks;
       unsigned Cnt = 1;
       Toks.push_back(Tok);
-      while (Cnt && Tok.isNot(tok::eof)) {
+      while (Cnt && !isAtInputEnd(Tok)) {
         (void)ConsumeAnyToken();
         if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp))
           ++Cnt;
diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp
index def2817c930b2..f84f43b0e7c40 100644
--- a/clang/lib/Parse/ParsePragma.cpp
+++ b/clang/lib/Parse/ParsePragma.cpp
@@ -1063,7 +1063,7 @@ void Parser::HandlePragmaMSPragma() {
   if (!(this->*Handler)(PragmaName, PragmaLocation)) {
     // Pragma handling failed, and has been diagnosed.  Slurp up the tokens
     // until eof (really end of line) to prevent follow-on errors.
-    while (Tok.isNot(tok::eof))
+    while (!isAtInputEnd(Tok))
       PP.Lex(Tok);
     PP.Lex(Tok);
   }
@@ -1140,7 +1140,7 @@ bool Parser::HandlePragmaMSSection(StringRef PragmaName,
     return false;
   }
   PP.Lex(Tok); // )
-  if (Tok.isNot(tok::eof)) {
+  if (!isAtInputEnd(Tok)) {
     PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
         << PragmaName;
     return false;
@@ -1222,7 +1222,7 @@ bool Parser::HandlePragmaMSSegment(StringRef PragmaName,
     return false;
   }
   PP.Lex(Tok); // )
-  if (Tok.isNot(tok::eof)) {
+  if (!isAtInputEnd(Tok)) {
     PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
         << PragmaName;
     return false;
@@ -1596,7 +1596,7 @@ bool Parser::HandlePragmaLoopHint(LoopHint &Hint) {
       if (Toks.size() > 2) {
         Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
             << PragmaLoopHintString(Info->PragmaName, Info->Option);
-        while (Tok.isNot(tok::eof))
+        while (!isAtInputEnd(Tok))
           ConsumeAnyToken();
       }
 
@@ -1631,10 +1631,10 @@ bool Parser::HandlePragmaLoopHint(LoopHint &Hint) {
 
       // Tokens following an error in an ill-formed constant expression will
       // remain in the token stream and must be removed.
-      if (Tok.isNot(tok::eof)) {
+      if (!isAtInputEnd(Tok)) {
         Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
             << PragmaLoopHintString(Info->PragmaName, Info->Option);
-        while (Tok.isNot(tok::eof))
+        while (!isAtInputEnd(Tok))
           ConsumeAnyToken();
       }
 
@@ -1657,10 +1657,10 @@ bool Parser::HandlePragmaLoopHint(LoopHint &Hint) {
 
     // Tokens following an error in an ill-formed constant expression will
     // remain in the token stream and must be removed.
-    if (Tok.isNot(tok::eof)) {
+    if (!isAtInputEnd(Tok)) {
       Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
           << PragmaLoopHintString(Info->PragmaName, Info->Option);
-      while (Tok.isNot(tok::eof))
+      while (!isAtInputEnd(Tok))
         ConsumeAnyToken();
     }
 
@@ -2113,7 +2113,7 @@ void Parser::HandlePragmaAttribute() {
 
   // Tokens following an ill-formed attribute will remain in the token stream
   // and must be removed.
-  if (Tok.isNot(tok::eof)) {
+  if (!isAtInputEnd(Tok)) {
     Diag(Tok, diag::err_pragma_attribute_extra_tokens_after_attribute);
     SkipToEnd();
     return;
@@ -2823,7 +2823,13 @@ void PragmaSupportHandler<StartTok, EndTok, UnexpectedDiag>::HandlePragma(
   Tok.setKind(StartTok);
   Tok.setLocation(Introducer.Loc);
 
-  while (Tok.isNot(tok::eod) && Tok.isNot(tok::eof)) {
+  auto IsAtInputEnd = [&PP](const Token &T) {
+    if (PP.getLangOpts().IncrementalExtensions)
+      return T.is(tok::annot_repl_input_end);
+    return T.is(tok::eof);
+  };
+
+  while (Tok.isNot(tok::eod) && !IsAtInputEnd(Tok)) {
     Pragma.push_back(Tok);
     PP.Lex(Tok);
     if (Tok.is(StartTok)) {
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 1f0f927053e51..2a3906fd5ca5e 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -1159,7 +1159,7 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
 
   bool LastIsError = false;
   while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
-         Tok.isNot(tok::eof) && Tok.isNot(tok::annot_repl_input_end)) {
+         !isAtInputEnd(Tok)) {
     if (Tok.is(tok::annot_pragma_unused)) {
       HandlePragmaUnused();
       continue;
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index be9e0a39a3781..4f5aed482e552 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -310,7 +310,7 @@ bool Parser::SkipUntil(ArrayRef<tok::TokenKind> Toks, SkipUntilFlags Flags) {
     if (Toks.size() == 1 && Toks[0] == tok::eof &&
         !HasFlagsSet(Flags, StopAtSemi) &&
         !HasFlagsSet(Flags, StopAtCodeCompletion)) {
-      while (Tok.isNot(tok::eof))
+      while (!isAtInputEnd(Tok))
         ConsumeAnyToken();
       return true;
     }

>From 67a331276978583c1a196888988b33d1cdbfd734 Mon Sep 17 00:00:00 2001
From: anutosh491 <andersonbhat491 at gmail.com>
Date: Wed, 11 Feb 2026 14:38:58 +0530
Subject: [PATCH 3/4] Fix failing tests and add some tests

---
 clang/include/clang/Parse/Parser.h            |  7 +++---
 .../Interpreter/repl-input-end-recovery.cpp   | 22 +++++++++++++++++++
 2 files changed, 26 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/Interpreter/repl-input-end-recovery.cpp

diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 647ec8b0299ad..27fba6161eecb 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -725,9 +725,10 @@ class Parser : public CodeCompletionHandler {
   /// In incremental (REPL) mode, this checks for annot_repl_input_end.
   /// In normal compilation, this checks for EOF.
   bool isAtInputEnd(const Token &T) const {
-    if (getLangOpts().IncrementalExtensions)
-      return T.is(tok::annot_repl_input_end);
-    return T.is(tok::eof);
+    if (T.is(tok::eof))
+      return true;
+    return getLangOpts().IncrementalExtensions &&
+           T.is(tok::annot_repl_input_end);
   }
 
   static void setTypeAnnotation(Token &Tok, TypeResult T) {
diff --git a/clang/test/Interpreter/repl-input-end-recovery.cpp b/clang/test/Interpreter/repl-input-end-recovery.cpp
new file mode 100644
index 0000000000000..a06cfad85a0c8
--- /dev/null
+++ b/clang/test/Interpreter/repl-input-end-recovery.cpp
@@ -0,0 +1,22 @@
+// REQUIRES: host-supports-jit
+// RUN: cat %s | clang-repl -Xcc -Xclang -Xcc -verify -Xcc -Xclang -Xcc -verify-ignore-unexpected | FileCheck %s
+
+extern "C" int printf(const char *, ...);
+
+void foo() { int x = 5; // expected-error {{expected '}'}}
+int g1 = 0; void foo() { g1 = 5; } foo(); printf("g1 = %d\n", g1);
+// CHECK: g1 = 5
+
+void (*test)() = [](){ if } // expected-error {{expected '(' after 'if'}}
+int g2 = 0; void (*test)() = [](){ if (1) g2 = 7; }; test(); printf("g2 = %d\n", g2);
+// CHECK: g2 = 7
+
+namespace myspace { // expected-error {{expected '}'}}
+namespace myspace { int v = 11; } printf("v = %d\n", myspace::v);
+// CHECK: v = 11
+
+struct X { using type = int }; // expected-error {{expected ';' after alias declaration}}
+struct X { using type = int; }; X::type t = 3; printf("t = %d\n", t);
+// CHECK: t = 3
+
+%quit
\ No newline at end of file

>From ab6d0d899f8a01ed7e8b1023f235bf567dce8ae0 Mon Sep 17 00:00:00 2001
From: anutosh491 <andersonbhat491 at gmail.com>
Date: Wed, 11 Feb 2026 14:45:15 +0530
Subject: [PATCH 4/4] Improve the lambda too

---
 clang/lib/Parse/ParsePragma.cpp | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp
index f84f43b0e7c40..268452133af62 100644
--- a/clang/lib/Parse/ParsePragma.cpp
+++ b/clang/lib/Parse/ParsePragma.cpp
@@ -2824,9 +2824,10 @@ void PragmaSupportHandler<StartTok, EndTok, UnexpectedDiag>::HandlePragma(
   Tok.setLocation(Introducer.Loc);
 
   auto IsAtInputEnd = [&PP](const Token &T) {
-    if (PP.getLangOpts().IncrementalExtensions)
-      return T.is(tok::annot_repl_input_end);
-    return T.is(tok::eof);
+    if (T.is(tok::eof))
+      return true;
+    return getLangOpts().IncrementalExtensions &&
+           T.is(tok::annot_repl_input_end);
   };
 
   while (Tok.isNot(tok::eod) && !IsAtInputEnd(Tok)) {



More information about the cfe-commits mailing list