https://github.com/firmiana402 created 
https://github.com/llvm/llvm-project/pull/208435

This PR fixes two DW_OP_convert-related issues in LLDB. #208203 #208197

First, a nonzero DW_OP_convert operand must reference a DW_TAG_base_type DIE. 
LLDB previously accepted any DIE that happened to carry base-type-like size and 
encoding attributes. This patch rejects non-base-type DIEs before using them as 
DW_OP_convert target types.

Second, for base types that carry both DW_AT_bit_size and DW_AT_byte_size, LLDB 
previously derived the conversion width from DW_AT_byte_size * 8. This is 
incorrect for types such as C _BitInt(31), where DW_AT_bit_size describes the 
actual value width. This patch prefers DW_AT_bit_size when present and falls 
back to DW_AT_byte_size otherwise.

## Tests

Extended DWARFExpression.DW_OP_convert coverage to verify:

- non-DW_TAG_base_type DIEs are rejected as DW_OP_convert target types;
- DW_AT_bit_size is preferred over DW_AT_byte_size for conversion width.

>From 5f80116cf6c48cfb7423c175b901f00dc77ecdb1 Mon Sep 17 00:00:00 2001
From: firmiana402 <[email protected]>
Date: Thu, 9 Jul 2026 19:20:48 +0800
Subject: [PATCH 1/2] [lldb] Reject non-base type DIEs for DW_OP_convert

---
 .../Plugins/SymbolFile/DWARF/DWARFUnit.cpp    |  3 +++
 .../Expression/DWARFExpressionTest.cpp        | 22 ++++++++++++++++++-
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
index 4b02124e987e8..aea2267277656 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -724,6 +724,9 @@ DWARFUnit::GetDIEBitSizeAndSign(uint64_t 
relative_die_offset) const {
   DWARFDIE die = const_cast<DWARFUnit *>(this)->GetDIE(abs_die_offset);
   if (!die)
     return llvm::createStringError("cannot resolve DW_OP_convert type DIE");
+  if (die.Tag() != DW_TAG_base_type)
+    return llvm::createStringError(
+        "DW_OP_convert type DIE is not a DW_TAG_base_type");
   uint64_t encoding =
       die.GetAttributeValueAsUnsigned(DW_AT_encoding, DW_ATE_hi_user);
   uint64_t bit_size = die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8;
diff --git a/lldb/unittests/Expression/DWARFExpressionTest.cpp 
b/lldb/unittests/Expression/DWARFExpressionTest.cpp
index 75162ca0b5f3e..bb64425ca9426 100644
--- a/lldb/unittests/Expression/DWARFExpressionTest.cpp
+++ b/lldb/unittests/Expression/DWARFExpressionTest.cpp
@@ -445,6 +445,14 @@ TEST(DWARFExpression, DW_OP_convert) {
               Form:            DW_FORM_data1
             - Attribute:       DW_AT_byte_size
               Form:            DW_FORM_data1
+        - Code:            0x00000003
+          Tag:             DW_TAG_enumeration_type
+          Children:        DW_CHILDREN_no
+          Attributes:
+            - Attribute:       DW_AT_encoding
+              Form:            DW_FORM_data1
+            - Attribute:       DW_AT_byte_size
+              Form:            DW_FORM_data1
   debug_info:
     - Version:         4
       AddrSize:        8
@@ -493,15 +501,21 @@ TEST(DWARFExpression, DW_OP_convert) {
           Values:
             - Value:           0x000000000000000b # DW_ATE_numeric_string
             - Value:           0x0000000000000001
+        # 0x00000020:
+        - AbbrCode:        0x00000003
+          Values:
+            - Value:           0x0000000000000007 # DW_ATE_unsigned
+            - Value:           0x0000000000000004
         - AbbrCode:        0x00000000
 
 )";
-  // Compile unit relative offsets to each DW_TAG_base_type
+  // Compile unit relative offsets to type DIEs.
   uint8_t offs_uint32_t = 0x0000000e;
   uint8_t offs_uint64_t = 0x00000011;
   uint8_t offs_sint64_t = 0x00000014;
   uint8_t offs_uchar = 0x00000017;
   uint8_t offs_schar = 0x0000001a;
+  uint8_t offs_enum = 0x00000020;
 
   DWARFExpressionTester t(yamldata, /*cu_index=*/1);
   ASSERT_TRUE((bool)t.GetDwarfUnit());
@@ -575,6 +589,12 @@ TEST(DWARFExpression, DW_OP_convert) {
       t.Eval({DW_OP_const1s, 'X', DW_OP_convert, 0x1d}).takeError(),
       llvm::Failed());
 
+  // Not a DW_TAG_base_type.
+  EXPECT_THAT_ERROR(
+      t.Eval({DW_OP_const1s, 'X', DW_OP_convert, offs_enum}).takeError(),
+      llvm::FailedWithMessage(
+          "DW_OP_convert type DIE is not a DW_TAG_base_type"));
+
   // A non-zero DIE offset with no DWARF unit.
   EXPECT_THAT_ERROR(
       Evaluate({DW_OP_const1s, 'X', DW_OP_convert, 0x01}, nullptr, nullptr)

>From 8a192c1dde2e4bb8f55d8ee0b4aca3256fbb4a6a Mon Sep 17 00:00:00 2001
From: firmiana402 <[email protected]>
Date: Thu, 9 Jul 2026 19:23:06 +0800
Subject: [PATCH 2/2] [lldb] Prefer DW_AT_bit_size for DW_OP_convert type width

---
 .../Plugins/SymbolFile/DWARF/DWARFUnit.cpp    |  4 ++--
 .../Expression/DWARFExpressionTest.cpp        | 22 +++++++++++++++++++
 2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
index aea2267277656..3fe8bbb8fdf56 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -729,9 +729,9 @@ DWARFUnit::GetDIEBitSizeAndSign(uint64_t 
relative_die_offset) const {
         "DW_OP_convert type DIE is not a DW_TAG_base_type");
   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 bb64425ca9426..c5ce2c3ec7afb 100644
--- a/lldb/unittests/Expression/DWARFExpressionTest.cpp
+++ b/lldb/unittests/Expression/DWARFExpressionTest.cpp
@@ -453,6 +453,16 @@ TEST(DWARFExpression, DW_OP_convert) {
               Form:            DW_FORM_data1
             - Attribute:       DW_AT_byte_size
               Form:            DW_FORM_data1
+        - Code:            0x00000004
+          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
@@ -506,6 +516,12 @@ TEST(DWARFExpression, DW_OP_convert) {
           Values:
             - Value:           0x0000000000000007 # DW_ATE_unsigned
             - Value:           0x0000000000000004
+        # 0x00000023:
+        - AbbrCode:        0x00000004
+          Values:
+            - Value:           0x0000000000000005 # DW_ATE_signed
+            - Value:           0x0000000000000004
+            - Value:           0x000000000000001f
         - AbbrCode:        0x00000000
 
 )";
@@ -516,6 +532,7 @@ TEST(DWARFExpression, DW_OP_convert) {
   uint8_t offs_uchar = 0x00000017;
   uint8_t offs_schar = 0x0000001a;
   uint8_t offs_enum = 0x00000020;
+  uint8_t offs_sint31_t = 0x00000023;
 
   DWARFExpressionTester t(yamldata, /*cu_index=*/1);
   ASSERT_TRUE((bool)t.GetDwarfUnit());
@@ -569,6 +586,11 @@ 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.
   //

_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to