[Lldb-commits] [lldb] [lldb] Evaluate DW_OP_mod with unsigned arithmetic (PR #218383)
via lldb-commits
lldb-commits at lists.llvm.org
Mon Aug 24 05:00:35 PDT 2026
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 <13554966229 at 163.com>
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) {
More information about the lldb-commits
mailing list