]> granicus.if.org Git - llvm/commitdiff
[DWARF] Fix DWARFVerifier::DieRangeInfo::contains
authorFangrui Song <maskray@google.com>
Mon, 15 Apr 2019 10:02:36 +0000 (10:02 +0000)
committerFangrui Song <maskray@google.com>
Mon, 15 Apr 2019 10:02:36 +0000 (10:02 +0000)
It didn't handle empty LHS correctly. If two ranges of LHS were
contiguous and jointly contained one range of RHS, it could also be incorrect.

DWARFAddressRange::contains can be removed and its tests can be merged into DWARFVerifier::DieRangeInfo::contains

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358387 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/DebugInfo/DWARF/DWARFAddressRange.h
lib/DebugInfo/DWARF/DWARFVerifier.cpp
unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp

index 56d46c696fd6e2d8157c21b61f0c805de5df0912..2d5f9f3c7658547860af88fd78f5da0fa1c5d84a 100644 (file)
@@ -42,12 +42,6 @@ struct DWARFAddressRange {
     return LowPC < RHS.HighPC && RHS.LowPC < HighPC;
   }
 
-  /// Returns true if [LowPC, HighPC) fully contains [RHS.LowPC, RHS.HighPC).
-  bool contains(const DWARFAddressRange &RHS) const {
-    assert(valid() && RHS.valid());
-    return LowPC <= RHS.LowPC && RHS.HighPC <= HighPC;
-  }
-
   void dump(raw_ostream &OS, uint32_t AddressSize,
             DIDumpOptions DumpOpts = {}) const;
 };
index 43e83c83fd9016699c4ac600f71f79dbc482a7e5..a95c4f982c0beedb5c0a7881fbb009a487adea45 100644 (file)
@@ -60,28 +60,27 @@ DWARFVerifier::DieRangeInfo::insert(const DieRangeInfo &RI) {
 }
 
 bool DWARFVerifier::DieRangeInfo::contains(const DieRangeInfo &RHS) const {
-  // Both list of ranges are sorted so we can make this fast.
-
-  if (Ranges.empty() || RHS.Ranges.empty())
-    return false;
-
-  // Since the ranges are sorted we can advance where we start searching with
-  // this object's ranges as we traverse RHS.Ranges.
-  auto End = Ranges.end();
-  auto Iter = findRange(RHS.Ranges.front());
-
-  // Now linearly walk the ranges in this object and see if they contain each
-  // ranges from RHS.Ranges.
-  for (const auto &R : RHS.Ranges) {
-    while (Iter != End) {
-      if (Iter->contains(R))
-        break;
-      ++Iter;
+  auto I1 = Ranges.begin(), E1 = Ranges.end();
+  auto I2 = RHS.Ranges.begin(), E2 = RHS.Ranges.end();
+  if (I2 == E2)
+    return true;
+
+  DWARFAddressRange R = *I2;
+  while (I1 != E1) {
+    bool Covered = I1->LowPC <= R.LowPC;
+    if (R.LowPC == R.HighPC || (Covered && R.HighPC <= I1->HighPC)) {
+      if (++I2 == E2)
+        return true;
+      R = *I2;
+      continue;
     }
-    if (Iter == End)
+    if (!Covered)
       return false;
+    if (R.LowPC < I1->HighPC)
+      R.LowPC = I1->HighPC;
+    ++I1;
   }
-  return true;
+  return false;
 }
 
 bool DWARFVerifier::DieRangeInfo::intersects(const DieRangeInfo &RHS) const {
index d3643ca4bb7d722caf91275a43b587a1f98faf60..ef51ce0fbff9f756483671c2f61800f74f73cac1 100644 (file)
@@ -2983,72 +2983,34 @@ TEST(DWARFDebugInfo, TestDwarfVerifyNestedFunctions) {
   VerifySuccess(*DwarfContext);
 }
 
-TEST(DWARFDebugInfo, TestDwarfRangesContains) {
-  DWARFAddressRange R(0x10, 0x20);
+TEST(DWARFDebugInfo, TestDWARFDieRangeInfoContains) {
+  DWARFVerifier::DieRangeInfo Empty;
+  ASSERT_TRUE(Empty.contains(Empty));
 
-  //----------------------------------------------------------------------
-  // Test ranges that start before R...
-  //----------------------------------------------------------------------
-  // Other range ends before start of R
-  ASSERT_FALSE(R.contains({0x0f, 0x10}));
-  // Other range end address is start of a R
-  ASSERT_FALSE(R.contains({0x0f, 0x11}));
-  // Other range end address is at and of R
-  ASSERT_FALSE(R.contains({0x0f, 0x20}));
-  // Other range end address is past end of R
-  ASSERT_FALSE(R.contains({0x0f, 0x40}));
+  DWARFVerifier::DieRangeInfo Ranges(
+      {{0x10, 0x20}, {0x30, 0x40}, {0x40, 0x50}});
+
+  ASSERT_TRUE(Ranges.contains(Empty));
+  ASSERT_FALSE(Ranges.contains({{{0x0f, 0x10}}}));
+  ASSERT_FALSE(Ranges.contains({{{0x0f, 0x20}}}));
+  ASSERT_FALSE(Ranges.contains({{{0x0f, 0x21}}}));
 
-  //----------------------------------------------------------------------
   // Test ranges that start at R's start address
-  //----------------------------------------------------------------------
-  // Ensure empty ranges matches
-  ASSERT_TRUE(R.contains({0x10, 0x10}));
-  // 1 byte of Range
-  ASSERT_TRUE(R.contains({0x10, 0x11}));
-  // same as Range
-  ASSERT_TRUE(R.contains({0x10, 0x20}));
-  // 1 byte past Range
-  ASSERT_FALSE(R.contains({0x10, 0x21}));
+  ASSERT_TRUE(Ranges.contains({{{0x10, 0x10}}}));
+  ASSERT_TRUE(Ranges.contains({{{0x10, 0x11}}}));
+  ASSERT_TRUE(Ranges.contains({{{0x10, 0x20}}}));
+  ASSERT_FALSE(Ranges.contains({{{0x10, 0x21}}}));
 
-  //----------------------------------------------------------------------
-  // Test ranges that start inside Range
-  //----------------------------------------------------------------------
-  // empty in range
-  ASSERT_TRUE(R.contains({0x11, 0x11}));
-  // all in Range
-  ASSERT_TRUE(R.contains({0x11, 0x1f}));
-  // ends at end of Range
-  ASSERT_TRUE(R.contains({0x11, 0x20}));
-  // ends past Range
-  ASSERT_FALSE(R.contains({0x11, 0x21}));
+  ASSERT_TRUE(Ranges.contains({{{0x11, 0x12}}}));
 
-  //----------------------------------------------------------------------
   // Test ranges that start at last bytes of Range
-  //----------------------------------------------------------------------
-  // ends at end of Range
-  ASSERT_TRUE(R.contains({0x1f, 0x20}));
-  // ends past Range
-  ASSERT_FALSE(R.contains({0x1f, 0x21}));
+  ASSERT_TRUE(Ranges.contains({{{0x1f, 0x20}}}));
+  ASSERT_FALSE(Ranges.contains({{{0x1f, 0x21}}}));
 
-  //----------------------------------------------------------------------
   // Test ranges that start after Range
-  //----------------------------------------------------------------------
-  // empty considered in Range
-  ASSERT_TRUE(R.contains({0x20, 0x20}));
-  // valid past Range
-  ASSERT_FALSE(R.contains({0x20, 0x21}));
-}
-
-TEST(DWARFDebugInfo, TestDWARFDieRangeInfoContains) {
-  DWARFVerifier::DieRangeInfo Ranges({{0x10, 0x20}, {0x30, 0x40}});
+  ASSERT_TRUE(Ranges.contains({{{0x20, 0x20}}}));
+  ASSERT_FALSE(Ranges.contains({{{0x20, 0x21}}}));
 
-  ASSERT_FALSE(Ranges.contains({{{0x0f, 0x10}}}));
-  ASSERT_FALSE(Ranges.contains({{{0x20, 0x30}}}));
-  ASSERT_FALSE(Ranges.contains({{{0x40, 0x41}}}));
-  ASSERT_TRUE(Ranges.contains({{{0x10, 0x20}}}));
-  ASSERT_TRUE(Ranges.contains({{{0x11, 0x12}}}));
-  ASSERT_TRUE(Ranges.contains({{{0x1f, 0x20}}}));
-  ASSERT_TRUE(Ranges.contains({{{0x30, 0x40}}}));
   ASSERT_TRUE(Ranges.contains({{{0x31, 0x32}}}));
   ASSERT_TRUE(Ranges.contains({{{0x3f, 0x40}}}));
   ASSERT_TRUE(Ranges.contains({{{0x10, 0x20}, {0x30, 0x40}}}));
@@ -3061,7 +3023,10 @@ TEST(DWARFDebugInfo, TestDWARFDieRangeInfoContains) {
                                  {0x31, 0x32},
                                  {0x32, 0x33}}}));
   ASSERT_FALSE(Ranges.contains(
-      {{{0x11, 0x12}, {0x12, 0x13}, {0x31, 0x32}, {0x32, 0x41}}}));
+      {{{0x11, 0x12}, {0x12, 0x13}, {0x31, 0x32}, {0x32, 0x51}}}));
+  ASSERT_TRUE(Ranges.contains({{{0x11, 0x12}, {0x30, 0x50}}}));
+  ASSERT_FALSE(Ranges.contains({{{0x30, 0x51}}}));
+  ASSERT_FALSE(Ranges.contains({{{0x50, 0x51}}}));
 }
 
 namespace {