<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/58769>58769</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            Bitfield incorrectly printed when using DWARF v2 and field crosses a storage unit
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            lldb
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          DavidSpickett
      </td>
    </tr>
</table>

<pre>
    Given the following source:
```
struct __attribute__((packed)) Foo {
  unsigned char a: 7;
  unsigned char b: 4;
};

int main() {
  volatile struct Foo f;
  f.a = 1;
  f.b = 2;
  return 0;
}
```
Note that "b" will cross into the next unsigned char of storage.

When clang produces DWARF v2 it describes the fields as follows:
```
$ ./bin/clang /tmp/test.c -o /tmp/test.o -gdwarf-2 && ./bin/llvm-dwarfdump /tmp/test.o
<...>
0x0000006f:     DW_TAG_member
                  DW_AT_name    ("a")
                  DW_AT_type    (0x00000099 "unsigned char")
                  DW_AT_decl_file       ("/tmp/test.c")
                  DW_AT_decl_line       (2)
                  DW_AT_byte_size       (0x01)
                  DW_AT_bit_size        (0x07)
                  DW_AT_bit_offset      (0x01)
                  DW_AT_data_member_location    (DW_OP_plus_uconst 0x0)

0x00000080:     DW_TAG_member
                  DW_AT_name    ("b")
                  DW_AT_type    (0x00000099 "unsigned char")
                  DW_AT_decl_file       ("/tmp/test.c")
                  DW_AT_decl_line       (3)
                  DW_AT_byte_size       (0x01)
                  DW_AT_bit_size        (0x04)
                  DW_AT_bit_offset      (0xfffffffffffffffd)
                  DW_AT_data_member_location    (DW_OP_plus_uconst 0x0)
```

Note that the DW_AT_bit_offset for "b" is `0xfffffffffffffffd`.

When I load this into lldb it cannot print the bitfield correctly (when stopped at the return):
```
(lldb) p f
(volatile Foo) $0 = (a = '\x01', b = '\0')
```

If I instead build with GCC 9.4.0 is gives:
```
0x0000003a:     DW_TAG_member
                  DW_AT_name    ("a")
                  DW_AT_decl_file       ("/tmp/test.c")
                  DW_AT_decl_line       (2)
                  DW_AT_decl_column     (0x11)
                  DW_AT_type    (0x00000060 "unsigned char")
                  DW_AT_byte_size       (0x01)
                  DW_AT_bit_size        (0x07)
                  DW_AT_bit_offset      (0x01)
                  DW_AT_data_member_location    (DW_OP_plus_uconst 0x0)

0x0000004a:     DW_TAG_member
                  DW_AT_name    ("b")
                  DW_AT_decl_file       ("/tmp/test.c")
                  DW_AT_decl_line       (3)
                  DW_AT_decl_column     (0x11)
                  DW_AT_type    (0x00000060 "unsigned char")
                  DW_AT_byte_size       (0x01)
                  DW_AT_bit_size        (0x04)
                  DW_AT_bit_offset      (-3)
                  DW_AT_data_member_location    (DW_OP_plus_uconst 0x0)
```

Now "b" is described as having a bit offset of -3. Which as a raw value would be the same as `0xfffffffffffffffd`.

lldb does not print this correctly either. GDB is fine with both which I take to mean both are valid.

I assume there is some byte level difference in the DWARF info causing llvm-dwarfdump to at least print the two values differently though.

I think lldb should be treating them as GDB does.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzlV0tv4zYQ_jXyZWBBL8v2QYckroNc2qJdIEeBIimLXUoURMre9Nd3SMmO7E023my7C2wFWbA4mvdwPk6h2FN2L_a8AVNxKJWU6iCaHWjVd5R78Y0XbLzgxkuD8Xav2nQ9NZDnxJhOFL3hee5FK7xbQj9y5kVrvGGrFHjL24EHoG-02DWcAa1IBwSFw9KLXyEXlpycyN5y8_zfPUVjoCaicXrXUz17JYkRksNopjWjnCgqfQJevIHwbK1wa9FkreOm7xoIzox4KRy_KsMxfsSAF0UF_uAgpATaKa0B7VQuuA3_ZC6cVCXaqDqy4_7UtccK80ElwTy0nWI95Ro2jzd_bGEfgTDAuKYYdlx1SRNcMg1Ej-nTr2XNixLwvWhb2KBtB_n4x9StfXJtfApzdbGkYL5jB9KV8wgpKd4TGVLu67mjsr5uLzlHrfGd7_te_MvwGnwK3JWWNsH22jzmH27u85rXBe-Osb-88KObD3lDam7fXM4jgj9baV9kMU_tkeWoer22eTrLxDWSGKcyL21dDddgxEUArxYkRTMR9DZT8YSbTIu_J0zoT_g2nzBTtpFveRWfKkvNzdfpY8SQMZe5VBQ3ompGfvzgt9_zVvY676lqtAGUeBJ4Xh6r4JvLo_h5yiP-zuWRvK88yvOL_YfFctHZLtqwbYuf2Vmq7tSfhQZkfsHiNPi8Ez-AVIShUDF2cylZYfswJU2jDPZoi0VWJ2pz3Rio6jpOjXyyrhysEOzzbYvlNFo3YIv159VmvbJqLLS1iF7HtRO2Iag52IuSwAEX0sj4Z-kt7lzucZffQTFZDdzal2L4UKK7AsPN0eOiF-jLQZgK7u_uYO0nfmBDt8MDw6soc9xGMfk-Df7HtmXHRJXs6-Z5H4Rv77sX-k4avKvv_M-AIfn2sroKGH5sO__ZyupdgDK_Ik7_MoAcpghxPGYze7auyN7ORcT2eBgNxeP7PPbhsRK0st8Q6MgB9kT2HA6qx95ZcNftta0_ciXmOHRhCk_3U3BBe55BhWNL5p0P95tba2hpq8u16ULh4-DseQBDPqJ6BTUnzUAhHbfmCXam8AFN033tTMUPUKBW-GYrACTfcwlMlCWSGorUZkRXO46IplSIgr22obkYBlAxYp3kRE8R0hzUECB9EmodMpXqd9WFVeh083EAW12dwtlxzDKqQ2m1jamNgY2WP-NZmKbLJIiXQThjWczW8ZrMjDCSZ7dHZBbNcxidWZheB9CDE6cxizQMRiy3Yxy32R1nNRzihJn1ncwqY1oHhNEW7x1moC98qupxNDpOSDjE_YUa8VVgoBE6o-1itUzXsyoL1isW0bRMkiSNFpTRIKVFQEKW0mhVsnQmScGlzrzFLVblcCKIvMVmJrIoiKIwDKJwkYRJ6Ae0SNdlQkLOgnKRxF4ScJyPpW9N8FW3m3WZs6bodxqJUmijn4lYArZBcKcJ5ZMec9JlGyx79mcrcKo3ZubMz5zt_wCskXHA">