[Lldb-commits] [lldb] 5c552c5 - [lldb] Fix GetExpressionPath for vector registers (#169210)
via lldb-commits
lldb-commits at lists.llvm.org
Tue Dec 2 09:10:13 PST 2025
Author: Ebuka Ezike
Date: 2025-12-02T17:10:08Z
New Revision: 5c552c5cff656f8f3b292fcfb527a8f1c0e52798
URL: https://github.com/llvm/llvm-project/commit/5c552c5cff656f8f3b292fcfb527a8f1c0e52798
DIFF: https://github.com/llvm/llvm-project/commit/5c552c5cff656f8f3b292fcfb527a8f1c0e52798.diff
LOG: [lldb] Fix GetExpressionPath for vector registers (#169210)
Vector registers have synthetic values for display purposes. This causes
SBValue::GetExpressionPath to dispatch
to ValueObjectSynthetic instead of ValueObjectRegister, producing
incorrect results.
Fixes #147144
Added:
lldb/test/API/python_api/exprpath_register/Makefile
lldb/test/API/python_api/exprpath_register/TestExprPathRegisters.py
lldb/test/API/python_api/exprpath_register/main.c
Modified:
lldb/include/lldb/ValueObject/ValueObjectSynthetic.h
lldb/source/ValueObject/ValueObjectSynthetic.cpp
Removed:
################################################################################
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..44e53bd5fd82e 100644
--- a/lldb/source/ValueObject/ValueObjectSynthetic.cpp
+++ b/lldb/source/ValueObject/ValueObjectSynthetic.cpp
@@ -443,3 +443,18 @@ void ValueObjectSynthetic::SetLanguageFlags(uint64_t flags) {
else
this->ValueObject::SetLanguageFlags(flags);
}
+
+void ValueObjectSynthetic::GetExpressionPath(Stream &stream,
+ GetExpressionPathFormat epformat) {
+ // A synthetic ValueObject may wrap an underlying Register or RegisterSet
+ // ValueObject, which requires a
diff erent approach to generating the
+ // expression path. In such cases, delegate to the non-synthetic value object.
+ 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;
+}
More information about the lldb-commits
mailing list