Index: llvm/include/llvm/DebugInfo/DWARF/DWARFAddressRange.h =================================================================== --- llvm/include/llvm/DebugInfo/DWARF/DWARFAddressRange.h +++ llvm/include/llvm/DebugInfo/DWARF/DWARFAddressRange.h @@ -34,11 +34,13 @@ /// dead-stripped ranges. bool valid() const { return LowPC <= HighPC; } + bool empty() const { return LowPC == HighPC; } + /// Returns true if [LowPC, HighPC) intersects with [RHS.LowPC, RHS.HighPC). bool intersects(const DWARFAddressRange &RHS) const { assert(valid() && RHS.valid()); // Empty ranges can't intersect. - if (LowPC == HighPC || RHS.LowPC == RHS.HighPC) + if (empty()) return false; return LowPC < RHS.HighPC && RHS.LowPC < HighPC; } Index: llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h =================================================================== --- llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h +++ llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h @@ -46,8 +46,6 @@ DieRangeInfo() = default; DieRangeInfo(DWARFDie Die) : Die(Die) {} - - /// Used for unit testing. DieRangeInfo(std::vector Ranges) : Ranges(std::move(Ranges)) {} Index: llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp =================================================================== --- llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp +++ llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp @@ -356,6 +356,38 @@ OS << "\n"; } + // Verify that location lists intersect with the parent's address range. + if (ParentRI.Die.isValid() && ParentRI.Die.getTag() != DW_TAG_inlined_subroutine) { + if (Optional BA = Die.getDwarfUnit()->getBaseAddress()) { + if (Optional FormValue = Die.find(DW_AT_location)) { + if (auto LocOffset = FormValue->getAsSectionOffset()) { + if (auto DebugLoc = DCtx.getDebugLoc()) { + if (auto LocList = DebugLoc->getLocationListAtOffset(*LocOffset)) { + // Build a list of address ranges from the location list. Don't + // use the insert method because according to the standard the + // ranges can overlap. + DieRangeInfo LocationRI; + for (auto Entry : LocList->Entries) { + LocationRI.Ranges.emplace_back(Entry.Begin + BA->Address, + Entry.End + BA->Address); + } + // Now make sure that at least one range overlaps with the parent + // range. + if (!ParentRI.Ranges.empty() && + !ParentRI.intersects(LocationRI)) { + error() << "No entry in the location list shares an address " + "range with its parent: "; + ParentRI.Die.dump(OS, 0); + Die.dump(OS, 2); + OS << "\n"; + } + } + } + } + } + } + } + // Verify that ranges are contained within their parent. bool ShouldBeContained = !Ranges.empty() && !ParentRI.Ranges.empty() && !(Die.getTag() == DW_TAG_subprogram &&