From bae9aedb341c5f4eceafba2ee1fec7c05d842c97 Mon Sep 17 00:00:00 2001 From: shafik Date: Thu, 12 Nov 2020 11:22:02 -0800 Subject: [PATCH] [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 --- .../Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp | 4 ++++ lldb/test/API/lang/cpp/bitfields/TestCppBitfields.py | 10 ++++++++++ lldb/test/API/lang/cpp/bitfields/main.cpp | 17 ++++++++++++++++- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 2003a24c04f..6633acd70a5 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -2581,7 +2581,11 @@ void DWARFASTParserClang::ParseSingleMember( // The ObjC runtime knows the byte offset but we still need to provide // the bit-offset in the layout. It just means something different then // what it does in C and C++. So we skip this check for ObjC types. + // + // We also skip this for fields of a union since they will all have a + // zero offset. if (!TypeSystemClang::IsObjCObjectOrInterfaceType(class_clang_type) && + !(parent_die.Tag() == DW_TAG_union_type && this_field_info.bit_offset == 0) && ((this_field_info.bit_offset >= parent_bit_size) || (last_field_info.IsBitfield() && !last_field_info.NextBitfieldOffsetIsValid( diff --git a/lldb/test/API/lang/cpp/bitfields/TestCppBitfields.py b/lldb/test/API/lang/cpp/bitfields/TestCppBitfields.py index 7320ce2b816..0585cf60951 100644 --- a/lldb/test/API/lang/cpp/bitfields/TestCppBitfields.py +++ b/lldb/test/API/lang/cpp/bitfields/TestCppBitfields.py @@ -46,6 +46,16 @@ class CppBitfieldsTestCase(TestBase): self.expect("expr (clang_example.f.a)", VARIABLES_DISPLAYED_CORRECTLY, substrs=['uint64_t', '1']) + self.expect("expr uwbf", + substrs=['a = 255', + 'b = 65535', + 'c = 4294967295', + 'x = 4294967295'] ) + + self.expect("expr uwubf", + substrs=['a = 16777215', + 'x = 4294967295'] ) + self.expect( "frame variable --show-types lba", VARIABLES_DISPLAYED_CORRECTLY, diff --git a/lldb/test/API/lang/cpp/bitfields/main.cpp b/lldb/test/API/lang/cpp/bitfields/main.cpp index 986b7cb947e..f9015b758c7 100644 --- a/lldb/test/API/lang/cpp/bitfields/main.cpp +++ b/lldb/test/API/lang/cpp/bitfields/main.cpp @@ -57,7 +57,7 @@ int main(int argc, char const *argv[]) { f.i = 1; f.j = 0; f.k = 1; - } + } } clang_example; class B { @@ -70,6 +70,18 @@ int main(int argc, char const *argv[]) { uint32_t d_a : 1; } derived; + union union_with_bitfields { + unsigned int a : 8; + unsigned int b : 16; + unsigned int c : 32; + unsigned int x; + } uwbf; + + union union_with_unnamed_bitfield { + unsigned int : 16, a : 24; + unsigned int x; + } uwubf; + lba.a = 2; lbb.a = 1; @@ -89,5 +101,8 @@ int main(int argc, char const *argv[]) { derived.b_a = 2; derived.d_a = 1; + uwbf.x = 0xFFFFFFFF; + uwubf.x = 0xFFFFFFFF; + return 0; // Set break point at this line. } -- 2.11.0