https://github.com/MrEven132 created 
https://github.com/llvm/llvm-project/pull/219395

`Evaluate_DW_OP_piece` returned early for a zero-sized piece before removing
its source location from the expression stack. A later non-empty piece could
then assemble the correct composite buffer while the stale source remained on
the stack and was returned instead.

Consume the source stack entry when a zero-sized piece has one, while still
contributing no bytes to the composite. Add a unit test covering a zero-sized
register piece followed by a non-empty register piece.

Fixes #209099


>From 1596755cc9687b57c9dbff23de6a577dab8ac419 Mon Sep 17 00:00:00 2001
From: MrEven132 <[email protected]>
Date: Fri, 28 Aug 2026 14:58:24 +0800
Subject: [PATCH] [lldb] Consume the source of zero-sized DW_OP_piece
 operations

---
 lldb/source/Expression/DWARFExpression.cpp       |  7 ++++++-
 .../unittests/Expression/DWARFExpressionTest.cpp | 16 ++++++++++++++++
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/lldb/source/Expression/DWARFExpression.cpp 
b/lldb/source/Expression/DWARFExpression.cpp
index d22634d63e875..3d238e0952b76 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -1112,8 +1112,13 @@ static llvm::Error Evaluate_DW_OP_piece(EvalContext 
&eval_ctx,
   // Reset for the next piece.
   eval_ctx.loc_desc_kind = Memory;
 
-  if (piece_byte_size == 0)
+  if (piece_byte_size == 0) {
+    // A zero-sized piece contributes no data, but it still consumes its source
+    // location description.
+    if (!eval_ctx.stack.empty())
+      eval_ctx.stack.pop_back();
     return llvm::Error::success();
+  }
 
   Value curr_piece;
 
diff --git a/lldb/unittests/Expression/DWARFExpressionTest.cpp 
b/lldb/unittests/Expression/DWARFExpressionTest.cpp
index aa8e17a88cc34..4f0c86bfaa426 100644
--- a/lldb/unittests/Expression/DWARFExpressionTest.cpp
+++ b/lldb/unittests/Expression/DWARFExpressionTest.cpp
@@ -2265,6 +2265,22 @@ TEST_F(DWARFExpressionMockProcessTest, 
DW_OP_piece_file_addr) {
                        ExpectHostAddress({0x11, 0x22}));
 }
 
+TEST_F(DWARFExpressionMockProcessTest, DW_OP_piece_zero_size) {
+  TestContext test_ctx;
+  ASSERT_TRUE(CreateTestContext(&test_ctx, "i386-pc-linux",
+                                RegisterValue(uint32_t{0x44332211})));
+
+  ExecutionContext exe_ctx(test_ctx.process_sp);
+  MockDwarfDelegate delegate = MockDwarfDelegate::Dwarf5();
+
+  // The zero-sized r3 piece contributes no bytes, but it must still consume
+  // its register location before the four-byte r0 piece is assembled.
+  EXPECT_THAT_EXPECTED(
+      Evaluate({DW_OP_reg3, DW_OP_piece, 0, DW_OP_reg0, DW_OP_piece, 4}, {},
+               &delegate, &exe_ctx, test_ctx.reg_ctx_sp.get()),
+      ExpectHostAddress({0x11, 0x22, 0x33, 0x44}));
+}
+
 class DWARFExpressionMockProcessTestWithAArch
     : public DWARFExpressionMockProcessTest {
 public:

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

Reply via email to