DWARF layout for bitfields is wrong when the bit offset is negative.

Some older versions of clang emitted bit offsets that were negative and these bitfields would have their bitfield-ness stripped off and it would cause a clang assertion in clang assertions were enabled. I updated the bitfield C test to make sure we don't regress.

<rdar://problem/21082998> 

llvm-svn: 267248
This commit is contained in:
Greg Clayton
2016-04-22 23:14:35 +00:00
parent 6010f97ee6
commit cae0855a62
3 changed files with 25 additions and 3 deletions

View File

@@ -96,6 +96,14 @@ class BitfieldsTestCase(TestBase):
self.expect("expr (more_bits.d)", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ['uint8_t', '\\0'])
self.expect("expr (packed.a)", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ['char', "'a'"])
self.expect("expr (packed.b)", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ['uint32_t', "10"])
self.expect("expr/x (packed.c)", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ['uint32_t', "7112233"])
@add_test_categories(['pyapi'])
@skipIfWindows # BitFields exhibit crashes in record layout on Windows (http://llvm.org/pr21800)
def test_and_python_api(self):

View File

@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include <stdint.h>
#include <stdio.h>
int main (int argc, char const *argv[])
{
struct Bits
@@ -62,6 +63,19 @@ int main (int argc, char const *argv[])
more_bits.c = 1;
more_bits.d = 0;
#pragma pack(1)
struct PackedBits
{
char a;
uint32_t b : 5,
c : 27;
};
#pragma pack()
struct PackedBits packed;
packed.a = 'a';
packed.b = 10;
packed.c = 0x7112233;
return 0; //// Set break point at this line.
}

View File

@@ -2671,7 +2671,7 @@ DWARFASTParserClang::ParseChildMembers(const SymbolContext &sc, const DWARFDIE &
AccessType accessibility = eAccessNone;
uint32_t member_byte_offset = (parent_die.Tag() == DW_TAG_union_type) ? 0 : UINT32_MAX;
size_t byte_size = 0;
size_t bit_offset = 0;
int64_t bit_offset = 0;
size_t bit_size = 0;
bool is_external = false; // On DW_TAG_members, this means the member is static
uint32_t i;
@@ -2688,7 +2688,7 @@ DWARFASTParserClang::ParseChildMembers(const SymbolContext &sc, const DWARFDIE &
case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
case DW_AT_name: name = form_value.AsCString(); break;
case DW_AT_type: encoding_form = form_value; break;
case DW_AT_bit_offset: bit_offset = form_value.Unsigned(); break;
case DW_AT_bit_offset: bit_offset = form_value.Signed(); break;
case DW_AT_bit_size: bit_size = form_value.Unsigned(); break;
case DW_AT_byte_size: byte_size = form_value.Unsigned(); break;
case DW_AT_data_member_location:
@@ -2802,7 +2802,7 @@ DWARFASTParserClang::ParseChildMembers(const SymbolContext &sc, const DWARFDIE &
// type in an expression when clang becomes unhappy with its
// recycled debug info.
if (bit_offset > 128)
if (byte_size == 0 && bit_offset < 0)
{
bit_size = 0;
bit_offset = 0;