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
