Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Infinite loop in parser due to using tok::annot_repl_input_end instead of tok::eof #541

Open
gnrv opened this issue Jan 23, 2025 · 0 comments
Labels

Comments

@gnrv
Copy link

gnrv commented Jan 23, 2025

  • [X ] Checked for duplicates

Describe the bug

$ bin/cling 

****************** CLING ******************
* Type C++ code and press enter to run it *
*             Type .q to exit             *
*******************************************
[cling]$ void (*test)() = [](){ if }
input_line_3:2:28: error: expected '(' after 'if'
 void (*test)() = [](){ if }
                           ^
input_line_3:4:2: error: expected ';' at end of declaration
}
 ^
 ;
<<< cling interactive line includer >>>:1:1: error: expected expression

^
<<< cling interactive line includer >>>:1:1: error: expected expression
<<< cling interactive line includer >>>:1:1: error: expected expression
<<< cling interactive line includer >>>:1:1: error: expected expression
<<< cling interactive line includer >>>:1:1: error: expected expression
<<< cling interactive line includer >>>:1:1: error: expected expression
<<< cling interactive line includer >>>:1:1: error: expected expression
<<< cling interactive line includer >>>:1:1: error: expected expression
<<< cling interactive line includer >>>:1:1: error: expected expression
<<< cling interactive line includer >>>:1:1: error: expected expression
<<< cling interactive line includer >>>:1:1: error: expected expression
<<< cling interactive line includer >>>:1:1: error: expected expression
<<< cling interactive line includer >>>:1:1: error: expected expression
<<< cling interactive line includer >>>:1:1: error: expected expression
<<< cling interactive line includer >>>:1:1: error: expected expression
<<< cling interactive line includer >>>:1:1: error: expected expression
<<< cling interactive line includer >>>:1:1: error: expected expression
fatal error: too many errors emitted, stopping now [-ferror-limit=]

The Parser is stuck in
StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr)

because there's a while loop that expects eof, but we're at annot_repl_input_end

  while (!tryParseMisplacedModuleImport() && Tok.isNot(tok::r_brace) &&
         Tok.isNot(tok::eof)) {
    if (Tok.is(tok::annot_pragma_unused)) {
      HandlePragmaUnused();
      continue;
    }
    ....

This turns into an infinite loop because it never encounters eof. I wonder if you guys are planning a general pattern to handle this thing without invasive modifications to llvm, or if there is some other general strategy. I'm a bit at a loss how to fix the bug in the optimal way, perhaps you guys can explain the best way to proceed.

This is not a bug in current released version of root, so I report it here instead of root repo.

Grepping through llvm, I see a lot of these kind of lines that don't seem to take annot_repl_input_end into account:

$ git grep isNot\(tok\:\:eof\)
...
clang/lib/Parse/ParseCXXInlineMethods.cpp:        if (Tok.isNot(tok::eof) || Tok.getEofData() != Param) {
clang/lib/Parse/ParseCXXInlineMethods.cpp:      while (Tok.isNot(tok::eof))
clang/lib/Parse/ParseCXXInlineMethods.cpp:    if (Tok.isNot(tok::eof) || Tok.getEofData() != LM.Method)
clang/lib/Parse/ParseCXXInlineMethods.cpp:    while (Tok.isNot(tok::eof))
clang/lib/Parse/ParseCXXInlineMethods.cpp:    while (Tok.isNot(tok::eof))
clang/lib/Parse/ParseCXXInlineMethods.cpp:      while (Tok.isNot(tok::eof))
clang/lib/Parse/ParseCXXInlineMethods.cpp:  while (Tok.isNot(tok::eof))
clang/lib/Parse/ParseCXXInlineMethods.cpp:  if (Tok.isNot(tok::eof)) {
clang/lib/Parse/ParseCXXInlineMethods.cpp:    while (Tok.isNot(tok::eof))
clang/lib/Parse/ParseCXXInlineMethods.cpp:  while (Tok.isNot(tok::eof))
clang/lib/Parse/ParseDecl.cpp:         Tok.isNot(tok::eof)) {
clang/lib/Parse/ParseDecl.cpp:      (Tok.isNot(tok::eof) || Tok.getEofData() != TypeStr.data())) {
clang/lib/Parse/ParseDecl.cpp:  while (Tok.isNot(tok::eof))
clang/lib/Parse/ParseDeclCXX.cpp:           Tok.isNot(tok::eof)) {
clang/lib/Parse/ParseDeclCXX.cpp:         Tok.isNot(tok::eof)) {
clang/lib/Parse/ParseDeclCXX.cpp:           Tok.isNot(tok::eof)) {
clang/lib/Parse/ParseExprCXX.cpp:    while (Tok.isNot(tok::eof))
clang/lib/Parse/ParseHLSL.cpp:  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
clang/lib/Parse/ParseObjc.cpp:      while (Tok.getLocation() != OrigLoc && Tok.isNot(tok::eof))
clang/lib/Parse/ParseOpenMP.cpp:      while (Cnt && Tok.isNot(tok::eof)) {
clang/lib/Parse/ParsePragma.cpp:    while (Tok.isNot(tok::eof))
clang/lib/Parse/ParsePragma.cpp:  if (Tok.isNot(tok::eof)) {
clang/lib/Parse/ParsePragma.cpp:  if (Tok.isNot(tok::eof)) {
clang/lib/Parse/ParsePragma.cpp:        while (Tok.isNot(tok::eof))
clang/lib/Parse/ParsePragma.cpp:      if (Tok.isNot(tok::eof)) {
clang/lib/Parse/ParsePragma.cpp:        while (Tok.isNot(tok::eof))
clang/lib/Parse/ParsePragma.cpp:    if (Tok.isNot(tok::eof)) {
clang/lib/Parse/ParsePragma.cpp:      while (Tok.isNot(tok::eof))
clang/lib/Parse/ParsePragma.cpp:  if (Tok.isNot(tok::eof)) {
clang/lib/Parse/ParsePragma.cpp:  while (Tok.isNot(tok::eod) && Tok.isNot(tok::eof)) {
clang/lib/Parse/ParseStmt.cpp:         Tok.isNot(tok::eof)) {
clang/lib/Parse/Parser.cpp:      while (Tok.isNot(tok::eof))
...

Expected behavior

Not hang in infinite loop

To Reproduce

See description

Setup

Latest cling in GitHub: commit 1d49255 (tag: __internal-root-4bcc5846f4e5c29d70e8f72029ec308c460671b7, upstream/master)

cling-latest llvm: commit 72c4df7523d41a5502e4a53b0999a6844ceb16e8 (HEAD, tag: cling-llvm18-20250117-01, origin/cling-llvm18, origin/cling-latest)

Additional context

@gnrv gnrv added the bug label Jan 23, 2025
gnrv added a commit to gnrv/QuickTex that referenced this issue Jan 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant