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
