summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2016-05-31 22:29:56 +0000
committerGreg Clayton <gclayton@apple.com>2016-05-31 22:29:56 +0000
commit892fa7dbcb631c5af36949ec16af4530e2b44eaf (patch)
treeab1cef061f31e512f3f6a6a048f5e870de4342aa
parented0b620a653091f225743ce790d260b1d6f6a97e (diff)
downloadbcm5719-llvm-892fa7dbcb631c5af36949ec16af4530e2b44eaf.tar.gz
bcm5719-llvm-892fa7dbcb631c5af36949ec16af4530e2b44eaf.zip
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> llvm-svn: 271343
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp52
1 files changed, 35 insertions, 17 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index ef434ee0393..41bdce53d44 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -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(const SymbolContext &sc, const DWARFDIE &
{
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;
OpenPOWER on IntegriCloud