[Lldb-commits] [lldb] [lldb][DIL] Fix infinite loop parsing cv-qualifiers in a C-style cast (PR #205087)

Yao Qi via lldb-commits lldb-commits at lists.llvm.org
Mon Jun 22 04:52:16 PDT 2026


https://github.com/qiyao created https://github.com/llvm/llvm-project/pull/205087

`ParseBuiltinType` loops over identifier tokens to assemble a builtin type
name.  When it encountered the "const" or "volatile" qualifier it executed
`continue` to skip the qualifier without first advancing the lexer, so the
loop re-examined the same token forever. Any cast expression beginning with
a cv-qualifier therefore hung the parser before any evaluation took place.

Advance past the qualifier token before continuing the loop.

Reproduce (hangs forever before the fix):
```
  $ ./bin/lldb ./bin/lldb
  (lldb) breakpoint set -n main
  (lldb) run
  (lldb) frame variable '(const int)1'
```
After the fix the qualifier is consumed and the cast evaluates normally
("(const int)1" -> 1); a bare qualifier with no type name is reported as an
ordinary parse error instead of hanging.

Adds regression coverage to the DIL Casts API test.


>From e19e9c8a1c13d69116e5b966f1d190e991df3b18 Mon Sep 17 00:00:00 2001
From: Yao Qi <yao_qi at apple.com>
Date: Sat, 20 Jun 2026 16:37:38 +0100
Subject: [PATCH] [lldb][DIL] Fix infinite loop parsing cv-qualifiers in a
 C-style cast

`ParseBuiltinType` loops over identifier tokens to assemble a builtin type
name.  When it encountered the "const" or "volatile" qualifier it executed
`continue` to skip the qualifier without first advancing the lexer, so the
loop re-examined the same token forever. Any cast expression beginning with
a cv-qualifier therefore hung the parser before any evaluation took place.

Advance past the qualifier token before continuing the loop.

Reproduce (hangs forever before the fix):
```
  $ ./bin/lldb ./bin/lldb
  (lldb) breakpoint set -n main
  (lldb) run
  (lldb) frame variable '(const int)1'
```
After the fix the qualifier is consumed and the cast evaluates normally
("(const int)1" -> 1); a bare qualifier with no type name is reported as an
ordinary parse error instead of hanging.

Adds regression coverage to the DIL Casts API test.
---
 lldb/source/ValueObject/DILParser.cpp             |  4 +++-
 .../var-dil/expr/Casts/TestFrameVarDILCast.py     | 15 +++++++++++++++
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/lldb/source/ValueObject/DILParser.cpp b/lldb/source/ValueObject/DILParser.cpp
index b57734a6a5114..b55b12a2bc42a 100644
--- a/lldb/source/ValueObject/DILParser.cpp
+++ b/lldb/source/ValueObject/DILParser.cpp
@@ -548,8 +548,10 @@ std::optional<CompilerType> DILParser::ParseBuiltinType() {
   bool first_word = true;
   while (CurToken().GetKind() == Token::identifier) {
     if (CurToken().GetSpelling() == "const" ||
-        CurToken().GetSpelling() == "volatile")
+        CurToken().GetSpelling() == "volatile") {
+      m_dil_lexer.Advance();
       continue;
+    }
     if (!first_word)
       type_name.push_back(' ');
     else
diff --git a/lldb/test/API/commands/frame/var-dil/expr/Casts/TestFrameVarDILCast.py b/lldb/test/API/commands/frame/var-dil/expr/Casts/TestFrameVarDILCast.py
index 77dabbfa800fb..567981cd670e9 100644
--- a/lldb/test/API/commands/frame/var-dil/expr/Casts/TestFrameVarDILCast.py
+++ b/lldb/test/API/commands/frame/var-dil/expr/Casts/TestFrameVarDILCast.py
@@ -286,6 +286,21 @@ def test_type_cast(self):
             substrs=["expected 'eof', got: <'InnerFoo' (identifier)>"],
         )
 
+        # cv-qualifiers in a cast must be consumed by the parser.
+        self.expect_var_path("(const int)1", value="1", type="int")
+        self.expect_var_path("(volatile int)1", value="1", type="int")
+        self.expect_var_path("(const volatile int)1", value="1", type="int")
+        self.expect(
+            "frame variable '(const)1'",
+            error=True,
+            substrs=["expected 'eof', got: <'1' (integer_constant)>"],
+        )
+        self.expect(
+            "frame variable '(volatile)1'",
+            error=True,
+            substrs=["expected 'eof', got: <'1' (integer_constant)>"],
+        )
+
         # Check that casts are not allowed in both simple and legacy modes
         frame = thread.GetFrameAtIndex(0)
         simple = frame.GetValueForVariablePath("(char)a", lldb.eDILModeSimple)



More information about the lldb-commits mailing list