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

LLDB currently passes the signed `Scalar` values produced by `DW_OP_consts`
directly to `Scalar::operator%`. As a result, the issue expression evaluates
`-1 % 2` as signed remainder `-1` instead of interpreting the all-one
address-sized value modulo 2 as `1`.

Make local copies of the `DW_OP_mod` dividend and divisor unsigned before
applying the existing modulo operator. The change is contained entirely in
the opcode evaluator and does not alter the global `Scalar` implementation.

Update the `DW_OP_mod` unit test with the issue reproducer.

Tests:

- `DWARFExpression.DW_OP_mod`
- `DWARFExpression.*`
- `ExpressionTests`
- `check-lldb-unit`
- `clang-format --dry-run --Werror`
- `git diff --check`

Fixes #207015


>From f6c0307f8f386e0730e775ef71b6a3332e7df6e0 Mon Sep 17 00:00:00 2001
From: MrEven132 <[email protected]>
Date: Mon, 24 Aug 2026 19:54:10 +0800
Subject: [PATCH] [lldb] Evaluate DW_OP_mod with unsigned arithmetic

---
 lldb/source/Expression/DWARFExpression.cpp        |  2 ++
 lldb/unittests/Expression/DWARFExpressionTest.cpp | 15 ++++++++++++---
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/lldb/source/Expression/DWARFExpression.cpp 
b/lldb/source/Expression/DWARFExpression.cpp
index 40c69c65853a8..129696012363b 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -1592,6 +1592,8 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
         return err;
       tmp = stack.back();
       stack.pop_back();
+      tmp.GetScalar().MakeUnsigned();
+      stack.back().GetScalar().MakeUnsigned();
       stack.back().GetScalar() = stack.back().GetScalar() % tmp.GetScalar();
       break;
 
diff --git a/lldb/unittests/Expression/DWARFExpressionTest.cpp 
b/lldb/unittests/Expression/DWARFExpressionTest.cpp
index b59bddff0cd1e..d66904769c543 100644
--- a/lldb/unittests/Expression/DWARFExpressionTest.cpp
+++ b/lldb/unittests/Expression/DWARFExpressionTest.cpp
@@ -953,9 +953,18 @@ TEST(DWARFExpression, DW_OP_div) {
 }
 
 TEST(DWARFExpression, DW_OP_mod) {
-  EXPECT_THAT_EXPECTED(Evaluate({DW_OP_const1s, static_cast<uint8_t>(-7),
-                                 DW_OP_const1s, 3, DW_OP_mod}),
-                       ExpectScalar(static_cast<int32_t>(-1)));
+  // DW_OP_mod uses unsigned remainder, so on a 64-bit target all-one bits
+  // modulo 2 is 1, not signed -1 % 2 == -1.
+  uint8_t expr[] = {DW_OP_consts, 0x7f,      DW_OP_consts,
+                    0x02,         DW_OP_mod, DW_OP_stack_value};
+  DataExtractor extractor(expr, sizeof(expr), lldb::eByteOrderLittle,
+                          /*addr_size=*/8);
+  auto result = DWARFExpression::Evaluate(
+      /*exe_ctx=*/nullptr, /*reg_ctx=*/nullptr, /*module_sp=*/{}, extractor,
+      /*unit=*/nullptr, lldb::eRegisterKindLLDB,
+      /*initial_value_ptr=*/nullptr, /*object_address_ptr=*/nullptr);
+  ASSERT_THAT_EXPECTED(result, ExpectScalar(64, 1, /*sign=*/false));
+  EXPECT_FALSE(result->GetScalar().IsSigned());
 }
 
 TEST(DWARFExpression, DW_OP_minus) {

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

Reply via email to