[Lldb-commits] [lldb] [lldb] Prefer DW_AT_bit_size for DW_OP_convert type width (PR #208478)
via lldb-commits
lldb-commits at lists.llvm.org
Thu Jul 9 08:24:17 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lldb
Author: firmiana402
<details>
<summary>Changes</summary>
This PR fixes a DW_OP_convert issue where LLDB derives the conversion width from DW_AT_byte_size * 8 before considering DW_AT_bit_size, #<!-- -->208203
For base types that carry both DW_AT_byte_size and DW_AT_bit_size, such as C _BitInt(31), DW_AT_bit_size describes the actual value width. LLDB should therefore prefer DW_AT_bit_size when it is present, and only fall back to DW_AT_byte_size otherwise.
## Tests
Extended DWARFExpression.DW_OP_convert coverage with a base type that has both DW_AT_byte_size and DW_AT_bit_size, and verifies that the conversion uses the DW_AT_bit_size width.
---
Full diff: https://github.com/llvm/llvm-project/pull/208478.diff
2 Files Affected:
- (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp (+2-2)
- (modified) lldb/unittests/Expression/DWARFExpressionTest.cpp (+23)
``````````diff
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
index 4b02124e987e8..974e0f6f875f5 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -726,9 +726,9 @@ DWARFUnit::GetDIEBitSizeAndSign(uint64_t relative_die_offset) const {
return llvm::createStringError("cannot resolve DW_OP_convert type DIE");
uint64_t encoding =
die.GetAttributeValueAsUnsigned(DW_AT_encoding, DW_ATE_hi_user);
- uint64_t bit_size = die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8;
+ uint64_t bit_size = die.GetAttributeValueAsUnsigned(DW_AT_bit_size, 0);
if (!bit_size)
- bit_size = die.GetAttributeValueAsUnsigned(DW_AT_bit_size, 0);
+ bit_size = die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8;
if (!bit_size)
return llvm::createStringError("unsupported type size");
bool sign;
diff --git a/lldb/unittests/Expression/DWARFExpressionTest.cpp b/lldb/unittests/Expression/DWARFExpressionTest.cpp
index 75162ca0b5f3e..6609c9da51bb0 100644
--- a/lldb/unittests/Expression/DWARFExpressionTest.cpp
+++ b/lldb/unittests/Expression/DWARFExpressionTest.cpp
@@ -445,6 +445,16 @@ TEST(DWARFExpression, DW_OP_convert) {
Form: DW_FORM_data1
- Attribute: DW_AT_byte_size
Form: DW_FORM_data1
+ - Code: 0x00000003
+ Tag: DW_TAG_base_type
+ Children: DW_CHILDREN_no
+ Attributes:
+ - Attribute: DW_AT_encoding
+ Form: DW_FORM_data1
+ - Attribute: DW_AT_byte_size
+ Form: DW_FORM_data1
+ - Attribute: DW_AT_bit_size
+ Form: DW_FORM_data1
debug_info:
- Version: 4
AddrSize: 8
@@ -493,6 +503,12 @@ TEST(DWARFExpression, DW_OP_convert) {
Values:
- Value: 0x000000000000000b # DW_ATE_numeric_string
- Value: 0x0000000000000001
+ # 0x00000020:
+ - AbbrCode: 0x00000003
+ Values:
+ - Value: 0x0000000000000005 # DW_ATE_signed
+ - Value: 0x0000000000000004
+ - Value: 0x000000000000001f
- AbbrCode: 0x00000000
)";
@@ -502,6 +518,7 @@ TEST(DWARFExpression, DW_OP_convert) {
uint8_t offs_sint64_t = 0x00000014;
uint8_t offs_uchar = 0x00000017;
uint8_t offs_schar = 0x0000001a;
+ uint8_t offs_sint31_t = 0x00000020;
DWARFExpressionTester t(yamldata, /*cu_index=*/1);
ASSERT_TRUE((bool)t.GetDwarfUnit());
@@ -555,6 +572,12 @@ TEST(DWARFExpression, DW_OP_convert) {
offs_schar, DW_OP_stack_value}),
ExpectScalar(8, 'A', is_signed));
+ // Prefer DW_AT_bit_size over DW_AT_byte_size when both are present.
+ EXPECT_THAT_EXPECTED(
+ t.Eval({DW_OP_const4u, 0x00, 0x00, 0x00, 0x40, DW_OP_convert,
+ offs_sint31_t, DW_OP_stack_value}),
+ ExpectScalar(31, 0x40000000, is_signed));
+
//
// Errors.
//
``````````
</details>
https://github.com/llvm/llvm-project/pull/208478
More information about the lldb-commits
mailing list