Author: Yao Qi Date: 2026-06-25T22:29:54-07:00 New Revision: 7f08b5508201caca4033c9af69237f970e55d902
URL: https://github.com/llvm/llvm-project/commit/7f08b5508201caca4033c9af69237f970e55d902 DIFF: https://github.com/llvm/llvm-project/commit/7f08b5508201caca4033c9af69237f970e55d902.diff LOG: [lldb][DIL] Fix infinite loop parsing cv-qualifiers in a C-style cast (#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. Added: Modified: lldb/source/ValueObject/DILParser.cpp lldb/test/API/commands/frame/var-dil/expr/Casts/TestFrameVarDILCast.py Removed: ################################################################################ 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) _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
