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

Reply via email to