Skip to content

Commit bae9aed

Browse files
committed
[LLDB] Fix handling of bit-fields in a union
When parsing DWARF and laying out bit-fields we don't properly take into account when they are in a union, they will all have a zero offset. Differential Revision: https://reviews.llvm.org/D91118
1 parent d5e89e8 commit bae9aed

File tree

3 files changed

+30
-1
lines changed

3 files changed

+30
-1
lines changed

lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2581,7 +2581,11 @@ void DWARFASTParserClang::ParseSingleMember(
25812581
// The ObjC runtime knows the byte offset but we still need to provide
25822582
// the bit-offset in the layout. It just means something different then
25832583
// what it does in C and C++. So we skip this check for ObjC types.
2584+
//
2585+
// We also skip this for fields of a union since they will all have a
2586+
// zero offset.
25842587
if (!TypeSystemClang::IsObjCObjectOrInterfaceType(class_clang_type) &&
2588+
!(parent_die.Tag() == DW_TAG_union_type && this_field_info.bit_offset == 0) &&
25852589
((this_field_info.bit_offset >= parent_bit_size) ||
25862590
(last_field_info.IsBitfield() &&
25872591
!last_field_info.NextBitfieldOffsetIsValid(

lldb/test/API/lang/cpp/bitfields/TestCppBitfields.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,16 @@ def test_and_run_command(self):
4646
self.expect("expr (clang_example.f.a)", VARIABLES_DISPLAYED_CORRECTLY,
4747
substrs=['uint64_t', '1'])
4848

49+
self.expect("expr uwbf",
50+
substrs=['a = 255',
51+
'b = 65535',
52+
'c = 4294967295',
53+
'x = 4294967295'] )
54+
55+
self.expect("expr uwubf",
56+
substrs=['a = 16777215',
57+
'x = 4294967295'] )
58+
4959
self.expect(
5060
"frame variable --show-types lba",
5161
VARIABLES_DISPLAYED_CORRECTLY,

lldb/test/API/lang/cpp/bitfields/main.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ int main(int argc, char const *argv[]) {
5757
f.i = 1;
5858
f.j = 0;
5959
f.k = 1;
60-
}
60+
}
6161
} clang_example;
6262

6363
class B {
@@ -70,6 +70,18 @@ int main(int argc, char const *argv[]) {
7070
uint32_t d_a : 1;
7171
} derived;
7272

73+
union union_with_bitfields {
74+
unsigned int a : 8;
75+
unsigned int b : 16;
76+
unsigned int c : 32;
77+
unsigned int x;
78+
} uwbf;
79+
80+
union union_with_unnamed_bitfield {
81+
unsigned int : 16, a : 24;
82+
unsigned int x;
83+
} uwubf;
84+
7385
lba.a = 2;
7486

7587
lbb.a = 1;
@@ -89,5 +101,8 @@ int main(int argc, char const *argv[]) {
89101
derived.b_a = 2;
90102
derived.d_a = 1;
91103

104+
uwbf.x = 0xFFFFFFFF;
105+
uwubf.x = 0xFFFFFFFF;
106+
92107
return 0; // Set break point at this line.
93108
}

0 commit comments

Comments
 (0)