Watch out for compilers that generate bad bitfield info. If the bit size of a bitfiel...
authorGreg Clayton <gclayton@apple.com>
Fri, 29 Apr 2016 21:26:46 +0000 (21:26 +0000)
committerGreg Clayton <gclayton@apple.com>
Fri, 29 Apr 2016 21:26:46 +0000 (21:26 +0000)
https://llvm.org/bugs/show_bug.cgi?id=27515
<rdar://problem/21082998>

llvm-svn: 268110

lldb/packages/Python/lldbsuite/test/lang/c/bitfields/TestBitfields.py
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp

index 5f67479..3caf916 100644 (file)
@@ -22,7 +22,6 @@ class BitfieldsTestCase(TestBase):
 
     @skipIfWindows # BitFields exhibit crashes in record layout on Windows (http://llvm.org/pr21800)
     @skipIf("llvm.org/pr27510", oslist=["linux"], compiler="clang", compiler_version=[">=", "3.9"]) # expectedFailure, skip to avoid crash
-    @skipIf("llvm.org/pr27515", oslist=["macosx"]) # Assertion failed: (Offset >= Size), function insertPadding CGRecordLayoutBuilder.cpp
     def test_and_run_command(self):
         """Test 'frame variable ...' on a variable with bitfields."""
         self.build()
index 0d53ccf..9451e49 100644 (file)
@@ -2645,6 +2645,10 @@ DWARFASTParserClang::ParseChildMembers(const SymbolContext &sc, const DWARFDIE &
     if (!parent_die)
         return 0;
 
+    // Get the parent byte size so we can verify any members will fit
+    const uint64_t parent_byte_size = parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size, UINT64_MAX) * 8;
+    const uint64_t parent_bit_size = parent_byte_size == UINT64_MAX ? UINT64_MAX : parent_byte_size * 8;
+
     uint32_t member_idx = 0;
     BitfieldInfo last_field_info;
 
@@ -2890,10 +2894,23 @@ DWARFASTParserClang::ParseChildMembers(const SymbolContext &sc, const DWARFDIE &
                                     if (byte_size == 0)
                                         byte_size = member_type->GetByteSize();
 
-                                    if (die.GetDWARF()->GetObjectFile()->GetByteOrder() == eByteOrderLittle)
+                                    ObjectFile *objfile = die.GetDWARF()->GetObjectFile();
+                                    if (objfile->GetByteOrder() == eByteOrderLittle)
                                     {
                                         this_field_info.bit_offset += byte_size * 8;
                                         this_field_info.bit_offset -= (bit_offset + bit_size);
+
+                                        if (this_field_info.bit_offset >= parent_bit_size)
+                                        {
+                                            objfile->GetModule()->ReportWarning("0x%8.8" PRIx64 ": %s bitfield named \"%s\" has invalid bit offset (0x%8.8" PRIx64 ") member will be ignored. Please file a bug against the compiler and include the preprocessed output for %s\n",
+                                                                                die.GetID(),
+                                                                                DW_TAG_value_to_name(tag),
+                                                                                name,
+                                                                                this_field_info.bit_offset,
+                                                                                sc.comp_unit ? sc.comp_unit->GetPath().c_str() : "the source file");
+                                            this_field_info.Clear();
+                                            continue;
+                                        }
                                     }
                                     else
                                     {