Author: MrEven132
Date: 2026-08-25T17:30:39+08:00
New Revision: f34b49eb72f12fa5be5623dea1c0a13ff518dab5

URL: 
https://github.com/llvm/llvm-project/commit/f34b49eb72f12fa5be5623dea1c0a13ff518dab5
DIFF: 
https://github.com/llvm/llvm-project/commit/f34b49eb72f12fa5be5623dea1c0a13ff518dab5.diff

LOG: [lldb] Evaluate DW_OP_mod with unsigned arithmetic (#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

Added: 
    

Modified: 
    lldb/source/Expression/DWARFExpression.cpp
    lldb/unittests/Expression/DWARFExpressionTest.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/source/Expression/DWARFExpression.cpp 
b/lldb/source/Expression/DWARFExpression.cpp
index 453c361c1d6f9..e62b6945dc3ed 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -1601,6 +1601,12 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
         return err;
       tmp = stack.back();
       stack.pop_back();
+      if (IsPotentiallyGenericIntegerOperand(tmp.GetScalar(), address_size) &&
+          IsPotentiallyGenericIntegerOperand(stack.back().GetScalar(),
+                                             address_size)) {
+        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 a09aadf88039c..76d2d4efcf557 100644
--- a/lldb/unittests/Expression/DWARFExpressionTest.cpp
+++ b/lldb/unittests/Expression/DWARFExpressionTest.cpp
@@ -992,9 +992,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