From 3ee34e14e164c247e7d631181179f77df90e069b Mon Sep 17 00:00:00 2001 From: "Duncan P. N. Exon Smith" Date: Tue, 31 Mar 2015 02:09:55 +0000 Subject: Verifier: Move over DISubprogram::Verify() Move over the remaining (somewhat complicated) check from `DISubprogram::Verify()`. I suspect this check could be optimized -- e.g., it would be nice not to do another full traversal here -- but it's not exactly obvious how. For now, just bring it over as is. Once we have a better model for the "canonical" subprogram of a `Function`, we should enforce that all `!dbg` attachments lead to the canonical one. llvm-svn: 233663 --- llvm/lib/IR/DebugInfo.cpp | 34 +--------------------------------- llvm/lib/IR/Verifier.cpp | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 33 deletions(-) (limited to 'llvm/lib') diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp index d841e3ca9c6..a59a879b436 100644 --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -256,39 +256,7 @@ bool DIType::Verify() const { return isType(); } bool DIBasicType::Verify() const { return isBasicType(); } bool DIDerivedType::Verify() const { return isDerivedType(); } bool DICompositeType::Verify() const { return isCompositeType(); } - -bool DISubprogram::Verify() const { - auto *N = dyn_cast_or_null(DbgNode); - if (!N) - return false; - - // If a DISubprogram has an llvm::Function*, then scope chains from all - // instructions within the function should lead to this DISubprogram. - if (auto *F = getFunction()) { - for (auto &BB : *F) { - for (auto &I : BB) { - MDLocation *DL = I.getDebugLoc(); - if (!DL) - continue; - - // walk the inlined-at scopes - MDScope *Scope = DL->getInlinedAtScope(); - if (!Scope) - return false; - while (!isa(Scope)) { - Scope = cast(Scope)->getScope(); - if (!Scope) - return false; - } - if (!DISubprogram(Scope).describes(F)) - return false; - } - } - } - - return true; -} - +bool DISubprogram::Verify() const { return isSubprogram(); } bool DIGlobalVariable::Verify() const { return isGlobalVariable(); } bool DIVariable::Verify() const { return isVariable(); } diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 171c16bc76b..2bd3f52f5d1 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -921,6 +921,45 @@ void Verifier::visitMDSubprogram(const MDSubprogram &N) { } Assert(!hasConflictingReferenceFlags(N.getFlags()), "invalid reference flags", &N); + + if (!N.getFunction()) + return; + + // FIXME: Should this be looking through bitcasts? + auto *F = dyn_cast(N.getFunction()->getValue()); + if (!F) + return; + + // Check that all !dbg attachments lead to back to N (or, at least, another + // subprogram that describes the same function). + // + // FIXME: Check this incrementally while visiting !dbg attachments. + // FIXME: Only check when N is the canonical subprogram for F. + SmallPtrSet Seen; + for (auto &BB : *F) + for (auto &I : BB) { + // Be careful about using MDLocation here since we might be dealing with + // broken code (this is the Verifier after all). + MDLocation *DL = + dyn_cast_or_null(I.getDebugLoc().getAsMDNode()); + if (!DL) + continue; + if (!Seen.insert(DL).second) + continue; + + MDLocalScope *Scope = DL->getInlinedAtScope(); + if (Scope && !Seen.insert(Scope).second) + continue; + + MDSubprogram *SP = Scope ? Scope->getSubprogram() : nullptr; + if (SP && !Seen.insert(SP).second) + continue; + + // FIXME: Once N is canonical, check "SP == &N". + Assert(DISubprogram(SP).describes(F), + "!dbg attachment points at wrong subprogram for function", &N, F, + &I, DL, Scope, SP); + } } void Verifier::visitMDLexicalBlockBase(const MDLexicalBlockBase &N) { -- cgit v1.2.3