Author: gclayton Date: Tue May 31 17:29:56 2016 New Revision: 271343 URL: http://llvm.org/viewvc/llvm-project?rev=271343&view=rev Log: Add more verification on consectutive bitfields otherwise clang will assert.
We need to verify that consecutive bitfields have higher offsets and don't overlap. The issues was found by running a broken version of recent clangs where the bitfield offsets were being emitted incorrectly. To guard against this we now verify and toss out any invalid bitfields and print a message that indicates to file a bug against the compiler. <rdar://problem/25737621> Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp?rev=271343&r1=271342&r2=271343&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp Tue May 31 17:29:56 2016 @@ -99,9 +99,9 @@ struct BitfieldInfo uint64_t bit_size; uint64_t bit_offset; - BitfieldInfo () : - bit_size (LLDB_INVALID_ADDRESS), - bit_offset (LLDB_INVALID_ADDRESS) + BitfieldInfo() : + bit_size(LLDB_INVALID_ADDRESS), + bit_offset(LLDB_INVALID_ADDRESS) { } @@ -112,10 +112,28 @@ struct BitfieldInfo bit_offset = LLDB_INVALID_ADDRESS; } - bool IsValid () + bool + IsValid() const { return (bit_size != LLDB_INVALID_ADDRESS) && - (bit_offset != LLDB_INVALID_ADDRESS); + (bit_offset != LLDB_INVALID_ADDRESS); + } + + bool + NextBitfieldOffsetIsValid(const uint64_t next_bit_offset) const + { + if (IsValid()) + { + // This bitfield info is valid, so any subsequent bitfields + // must not overlap and must be at a higher bit offset than + // any previous bitfield + size. + return (bit_size + bit_offset) <= next_bit_offset; + } + else + { + // If the this BitfieldInfo is not valid, then any offset isOK + return true; + } } }; @@ -2965,24 +2983,24 @@ DWARFASTParserClang::ParseChildMembers(c { 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 { this_field_info.bit_offset += bit_offset; } + if ((this_field_info.bit_offset >= parent_bit_size) || !last_field_info.NextBitfieldOffsetIsValid(this_field_info.bit_offset)) + { + 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; + } + // Update the field bit offset we will report for layout field_bit_offset = this_field_info.bit_offset; _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits