[clang-tools-extra] edb8fb2 - [pseudo] Fix HeadsPartition is not initialized correctly.

Haojian Wu via cfe-commits cfe-commits at lists.llvm.org
Tue Aug 23 06:10:11 PDT 2022


Author: Haojian Wu
Date: 2022-08-23T15:08:33+02:00
New Revision: edb8fb265990c3c4d0453d6b789554ccb5341123

URL: https://github.com/llvm/llvm-project/commit/edb8fb265990c3c4d0453d6b789554ccb5341123
DIFF: https://github.com/llvm/llvm-project/commit/edb8fb265990c3c4d0453d6b789554ccb5341123.diff

LOG: [pseudo] Fix HeadsPartition is not initialized correctly.

The bug was that if we recover from the token 0, we will make the
Heads empty (Line646), which results no recovery being applied.

Reviewed By: sammccall

Differential Revision: https://reviews.llvm.org/D132388

Added: 
    

Modified: 
    clang-tools-extra/pseudo/lib/GLR.cpp
    clang-tools-extra/pseudo/unittests/GLRTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/pseudo/lib/GLR.cpp b/clang-tools-extra/pseudo/lib/GLR.cpp
index 8e4e6181eb2a6..3e7d5a5435807 100644
--- a/clang-tools-extra/pseudo/lib/GLR.cpp
+++ b/clang-tools-extra/pseudo/lib/GLR.cpp
@@ -31,7 +31,6 @@ Token::Index findRecoveryEndpoint(ExtensionID Strategy, Token::Index Begin,
                                   const TokenStream &Tokens,
                                   const Language &Lang) {
   assert(Strategy != 0);
-  assert(Begin > 0);
   if (auto S = Lang.RecoveryStrategies.lookup(Strategy))
     return S(Begin, Tokens);
   return Token::Invalid;
@@ -614,7 +613,7 @@ const ForestNode &glrParse(const ParseParams &Params, SymbolID StartSymbol,
   // Invariant: Heads is partitioned by source: {shifted | reduced}.
   // HeadsPartition is the index of the first head formed by reduction.
   // We use this to discard and recreate the reduced heads during recovery.
-  unsigned HeadsPartition = 0;
+  unsigned HeadsPartition = Heads.size();
   std::vector<const GSS::Node *> NextHeads;
   auto MaybeGC = [&, Roots(std::vector<const GSS::Node *>{}), I(0u)]() mutable {
     assert(NextHeads.empty() && "Running GC at the wrong time!");

diff  --git a/clang-tools-extra/pseudo/unittests/GLRTest.cpp b/clang-tools-extra/pseudo/unittests/GLRTest.cpp
index 761b2c8db4aac..f361fb78247ac 100644
--- a/clang-tools-extra/pseudo/unittests/GLRTest.cpp
+++ b/clang-tools-extra/pseudo/unittests/GLRTest.cpp
@@ -652,6 +652,31 @@ TEST_F(GLRTest, RecoverUnrestrictedReduce) {
             "[  1, end) └─word := <opaque>\n");
 }
 
+TEST_F(GLRTest, RecoveryFromStartOfInput) {
+  build(R"bnf(
+    _ := start [recover=Fallback] EOF
+
+    start := IDENTIFIER
+  )bnf");
+  TestLang.Table = LRTable::buildSLR(TestLang.G);
+  bool fallback_recovered = false;
+  auto fallback = [&](Token::Index Start, const TokenStream & Code) {
+    fallback_recovered = true;
+    return Code.tokens().size();
+  };
+  TestLang.RecoveryStrategies.try_emplace(
+      extensionID("Fallback"),
+      fallback);
+  clang::LangOptions LOptions;
+  TokenStream Tokens = cook(lex("?", LOptions), LOptions);
+
+  const ForestNode &Parsed =
+      glrParse({Tokens, Arena, GSStack}, id("start"), TestLang);
+  EXPECT_TRUE(fallback_recovered);
+  EXPECT_EQ(Parsed.dumpRecursive(TestLang.G),
+            "[  0, end) start := <opaque>\n");
+}
+
 TEST_F(GLRTest, RepeatedRecovery) {
   // We require multiple steps of recovery at eof and then a reduction in order
   // to successfully parse.


        


More information about the cfe-commits mailing list