https://github.com/da-viper created 
https://github.com/llvm/llvm-project/pull/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

>From c389000696408c75abc4c3f851c703f58f54d873 Mon Sep 17 00:00:00 2001
From: Ebuka Ezike <[email protected]>
Date: Sun, 23 Nov 2025 01:11:47 +0000
Subject: [PATCH 1/4] [lldb] Fix `GetExpressionPath` for vector registers

Vector registers have synthetic values for display purposes.
This causes SBValue::GetExpressionPath to dispatch
to ValueObjectSynthetic instead of ValueObjectRegister,
producing incorrect results.
---
 lldb/include/lldb/ValueObject/ValueObjectSynthetic.h |  5 +++++
 lldb/source/ValueObject/ValueObjectSynthetic.cpp     | 12 ++++++++++++
 2 files changed, 17 insertions(+)

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..b2babb14a0e56 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);
+}
\ No newline at end of file

>From f91a2a97baeea75102a170bb4e27222de90539cd Mon Sep 17 00:00:00 2001
From: Ebuka Ezike <[email protected]>
Date: Sun, 23 Nov 2025 03:10:22 +0000
Subject: [PATCH 2/4] [lldb] add test case

---
 .../API/python_api/exprpath_register/Makefile |  3 +
 .../TestExprPathRegisters.py                  | 64 +++++++++++++++++++
 .../API/python_api/exprpath_register/main.c   | 10 +++
 3 files changed, 77 insertions(+)
 create mode 100644 lldb/test/API/python_api/exprpath_register/Makefile
 create mode 100644 
lldb/test/API/python_api/exprpath_register/TestExprPathRegisters.py
 create mode 100644 lldb/test/API/python_api/exprpath_register/main.c

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..791014ba63fc8
--- /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;
+}
\ No newline at end of file

>From 235a6601f4b7b088e9780fabc68006aa8e66bd0e Mon Sep 17 00:00:00 2001
From: Ebuka Ezike <[email protected]>
Date: Sun, 23 Nov 2025 03:16:14 +0000
Subject: [PATCH 3/4] [lldb] add new line

---
 lldb/source/ValueObject/ValueObjectSynthetic.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lldb/source/ValueObject/ValueObjectSynthetic.cpp 
b/lldb/source/ValueObject/ValueObjectSynthetic.cpp
index b2babb14a0e56..1b689257224df 100644
--- a/lldb/source/ValueObject/ValueObjectSynthetic.cpp
+++ b/lldb/source/ValueObject/ValueObjectSynthetic.cpp
@@ -454,4 +454,4 @@ void ValueObjectSynthetic::GetExpressionPath(Stream &stream,
       return raw_value->GetExpressionPath(stream, epformat);
   }
   return ValueObject::GetExpressionPath(stream, epformat);
-}
\ No newline at end of file
+}

>From b30b9e4ef22762f63023c4bcd2a80b0bd13f19b5 Mon Sep 17 00:00:00 2001
From: Ebuka Ezike <[email protected]>
Date: Sun, 23 Nov 2025 10:49:15 +0000
Subject: [PATCH 4/4] [lldb] add new line

---
 lldb/test/API/python_api/exprpath_register/main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lldb/test/API/python_api/exprpath_register/main.c 
b/lldb/test/API/python_api/exprpath_register/main.c
index 791014ba63fc8..4809a87cdf210 100644
--- a/lldb/test/API/python_api/exprpath_register/main.c
+++ b/lldb/test/API/python_api/exprpath_register/main.c
@@ -7,4 +7,4 @@ float my_foo() {
 int main(void) {
   float result = my_foo();
   return (int)result;
-}
\ No newline at end of file
+}

_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to