[Lldb-commits] [lldb] Zero extend APInt when piece size is bigger than the bitwidth (PR #150149)
via lldb-commits
lldb-commits at lists.llvm.org
Tue Jul 22 22:55:26 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lldb
Author: satyanarayana reddy janga (satyajanga)
<details>
<summary>Changes</summary>
### Summary
We have internally seen cases like this
`DW_OP_lit0, DW_OP_stack_value, DW_OP_piece 0x28`
where we have longer op pieces than what Scalar supports (32, 64 or 128 bits). In these cases LLDB is currently hitting the assertion `assert(ap_int.getBitWidth() >= bit_size);`
We are extending the generated APInt to the piece size by filling zeros.
### Test plan
Added a unit to cover this case.
---
Full diff: https://github.com/llvm/llvm-project/pull/150149.diff
2 Files Affected:
- (modified) lldb/source/Expression/DWARFExpression.cpp (+6-1)
- (modified) lldb/unittests/Expression/DWARFExpressionTest.cpp (+21)
``````````diff
diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp
index 52891fcefd68b..c00795b97467b 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -1978,7 +1978,12 @@ llvm::Expected<Value> DWARFExpression::Evaluate(
// grows to the nearest host integer type.
llvm::APInt fail_value(1, 0, false);
llvm::APInt ap_int = scalar.UInt128(fail_value);
- assert(ap_int.getBitWidth() >= bit_size);
+ // We have seen a case where we have expression like:
+ // DW_OP_lit0, DW_OP_stack_value, DW_OP_piece 0x28
+ // here we are assuming the compiler was trying to zero
+ // extend the value that we should append to the buffer.
+ if (ap_int.getBitWidth() < bit_size)
+ ap_int = ap_int.zext(bit_size);
llvm::ArrayRef<uint64_t> buf{ap_int.getRawData(),
ap_int.getNumWords()};
curr_piece.GetScalar() = Scalar(llvm::APInt(bit_size, buf));
diff --git a/lldb/unittests/Expression/DWARFExpressionTest.cpp b/lldb/unittests/Expression/DWARFExpressionTest.cpp
index fdc9bfae1876c..86c3b56e320fd 100644
--- a/lldb/unittests/Expression/DWARFExpressionTest.cpp
+++ b/lldb/unittests/Expression/DWARFExpressionTest.cpp
@@ -358,6 +358,27 @@ TEST(DWARFExpression, DW_OP_piece) {
llvm::HasValue(GetScalar(16, 0xff00, true)));
}
+TEST(DWARFExpression, DW_OP_piece_host_address) {
+ static const uint8_t expr_data[] = {DW_OP_lit2, DW_OP_stack_value,
+ DW_OP_piece, 40};
+ llvm::ArrayRef<uint8_t> expr(expr_data, sizeof(expr_data));
+ DataExtractor extractor(expr.data(), expr.size(), lldb::eByteOrderLittle, 4);
+
+ // This tests if ap_int is extended to the right width.
+ // expect 40*8 = 320 bits size.
+ llvm::Expected<Value> result =
+ DWARFExpression::Evaluate(nullptr, nullptr, nullptr, extractor, nullptr,
+ lldb::eRegisterKindDWARF, nullptr, nullptr);
+ ASSERT_THAT_EXPECTED(result, llvm::Succeeded());
+ ASSERT_EQ(result->GetValueType(), Value::ValueType::HostAddress);
+ ASSERT_EQ(result->GetBuffer().GetByteSize(), 40ul);
+ const uint8_t *data = result->GetBuffer().GetBytes();
+ ASSERT_EQ(data[0], 2);
+ for (int i = 1; i < 40; i++) {
+ ASSERT_EQ(data[i], 0);
+ }
+}
+
TEST(DWARFExpression, DW_OP_implicit_value) {
unsigned char bytes = 4;
``````````
</details>
https://github.com/llvm/llvm-project/pull/150149
More information about the lldb-commits
mailing list