[Lldb-commits] [lldb] [lldb] Fix GetExpressionPath for vector registers (PR #169210)
via lldb-commits
lldb-commits at lists.llvm.org
Sun Nov 23 03:07:23 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lldb
Author: Ebuka Ezike (da-viper)
<details>
<summary>Changes</summary>
Vector registers have synthetic values for display purposes. This causes SBValue::GetExpressionPath to dispatch
to ValueObjectSynthetic instead of ValueObjectRegister, producing incorrect results.
Fixes #<!-- -->147144
---
Full diff: https://github.com/llvm/llvm-project/pull/169210.diff
5 Files Affected:
- (modified) lldb/include/lldb/ValueObject/ValueObjectSynthetic.h (+5)
- (modified) lldb/source/ValueObject/ValueObjectSynthetic.cpp (+12)
- (added) lldb/test/API/python_api/exprpath_register/Makefile (+3)
- (added) lldb/test/API/python_api/exprpath_register/TestExprPathRegisters.py (+64)
- (added) lldb/test/API/python_api/exprpath_register/main.c (+10)
``````````diff
diff --git a/lldb/include/lldb/ValueObject/ValueObjectSynthetic.h b/lldb/include/lldb/ValueObject/ValueObjectSynthetic.h
index 063d796ee4eec..1a82fd78bbba3 100644
--- a/lldb/include/lldb/ValueObject/ValueObjectSynthetic.h
+++ b/lldb/include/lldb/ValueObject/ValueObjectSynthetic.h
@@ -123,6 +123,11 @@ class ValueObjectSynthetic : public ValueObject {
void SetLanguageFlags(uint64_t flags) override;
+ void
+ GetExpressionPath(Stream &stream,
+ GetExpressionPathFormat epformat =
+ eGetExpressionPathFormatDereferencePointers) override;
+
protected:
bool UpdateValue() override;
diff --git a/lldb/source/ValueObject/ValueObjectSynthetic.cpp b/lldb/source/ValueObject/ValueObjectSynthetic.cpp
index f673c51a88412..1b689257224df 100644
--- a/lldb/source/ValueObject/ValueObjectSynthetic.cpp
+++ b/lldb/source/ValueObject/ValueObjectSynthetic.cpp
@@ -443,3 +443,15 @@ void ValueObjectSynthetic::SetLanguageFlags(uint64_t flags) {
else
this->ValueObject::SetLanguageFlags(flags);
}
+
+void ValueObjectSynthetic::GetExpressionPath(Stream &stream,
+ GetExpressionPathFormat epformat) {
+ if (const lldb::ValueType obj_value_type = GetValueType();
+ IsSynthetic() && (obj_value_type == lldb::eValueTypeRegister ||
+ obj_value_type == lldb::eValueTypeRegisterSet)) {
+
+ if (const lldb::ValueObjectSP raw_value = GetNonSyntheticValue())
+ return raw_value->GetExpressionPath(stream, epformat);
+ }
+ return ValueObject::GetExpressionPath(stream, epformat);
+}
diff --git a/lldb/test/API/python_api/exprpath_register/Makefile b/lldb/test/API/python_api/exprpath_register/Makefile
new file mode 100644
index 0000000000000..10495940055b6
--- /dev/null
+++ b/lldb/test/API/python_api/exprpath_register/Makefile
@@ -0,0 +1,3 @@
+C_SOURCES := main.c
+
+include Makefile.rules
diff --git a/lldb/test/API/python_api/exprpath_register/TestExprPathRegisters.py b/lldb/test/API/python_api/exprpath_register/TestExprPathRegisters.py
new file mode 100644
index 0000000000000..4ffbc5e49fb0d
--- /dev/null
+++ b/lldb/test/API/python_api/exprpath_register/TestExprPathRegisters.py
@@ -0,0 +1,64 @@
+"""
+Test Getting the expression path for registers works correctly
+"""
+
+import lldb
+from lldbsuite.test import lldbutil
+from lldbsuite.test.lldbtest import TestBase, VALID_BREAKPOINT, VALID_TARGET
+
+
+class TestExprPathRegisters(TestBase):
+ NO_DEBUG_INFO_TESTCASE = True
+
+ def verify_register_path(self, reg_value: lldb.SBValue):
+ stream = lldb.SBStream()
+ reg_name = reg_value.name
+ self.assertTrue(
+ reg_value.GetExpressionPath(stream),
+ f"Expected an expression path for register {reg_name}.",
+ )
+ reg_expr_path = stream.GetData()
+ self.assertEqual(reg_expr_path, f"${reg_name}")
+
+ def test_float_registers(self):
+ """Verify the expression path of the registers is valid."""
+ self.build()
+ _, _, thread, _ = lldbutil.run_to_name_breakpoint(self, "my_foo")
+ frame = thread.GetSelectedFrame()
+ self.assertTrue(frame, "Expected a valid Frame.")
+
+ # possible floating point register on some cpus.
+ register_names = [
+ "xmm0",
+ "ymm0",
+ "v0",
+ "v1",
+ "f0",
+ "f1",
+ "d0",
+ "d1",
+ "vr0",
+ "vr1",
+ "st0",
+ "st1",
+ ]
+ for name in register_names:
+ reg_value = frame.FindRegister(name)
+ # some the register will not be available for the cpu
+ # only verify if it is valid.
+ if reg_value:
+ self.verify_register_path(reg_value)
+
+ def test_all_registers(self):
+ """Test all the registers that is avaiable on the machine"""
+ self.build()
+ _, _, thread, _ = lldbutil.run_to_name_breakpoint(self, "my_foo")
+ frame = thread.GetSelectedFrame()
+ self.assertTrue(frame, "Expected a valid Frame.")
+
+ register_sets = frame.GetRegisters()
+ self.assertTrue(register_sets.IsValid(), "Expected Frame Registers")
+
+ for register_set in register_sets:
+ for register in register_set.children:
+ self.verify_register_path(register)
diff --git a/lldb/test/API/python_api/exprpath_register/main.c b/lldb/test/API/python_api/exprpath_register/main.c
new file mode 100644
index 0000000000000..4809a87cdf210
--- /dev/null
+++ b/lldb/test/API/python_api/exprpath_register/main.c
@@ -0,0 +1,10 @@
+
+float my_foo() {
+ float result = 10.0 + 20.0;
+ return result;
+}
+
+int main(void) {
+ float result = my_foo();
+ return (int)result;
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/169210
More information about the lldb-commits
mailing list