summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2015-03-31 02:09:55 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2015-03-31 02:09:55 +0000
commit3ee34e14e164c247e7d631181179f77df90e069b (patch)
treead77f0095dbf0421ea25bc75abe23e1dd9d28e68
parentdd77af870f12d722652da0ed28a7c3dbd3da348e (diff)
downloadbcm5719-llvm-3ee34e14e164c247e7d631181179f77df90e069b.tar.gz
bcm5719-llvm-3ee34e14e164c247e7d631181179f77df90e069b.zip
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
-rw-r--r--llvm/lib/IR/DebugInfo.cpp34
-rw-r--r--llvm/lib/IR/Verifier.cpp39
-rw-r--r--llvm/unittests/IR/IRBuilderTest.cpp3
3 files changed, 42 insertions, 34 deletions
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<MDSubprogram>(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<MDSubprogram>(Scope)) {
- Scope = cast<MDLexicalBlockBase>(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<Function>(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<const MDNode *, 32> 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<MDLocation>(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) {
diff --git a/llvm/unittests/IR/IRBuilderTest.cpp b/llvm/unittests/IR/IRBuilderTest.cpp
index 3901fb85434..c721ef508bf 100644
--- a/llvm/unittests/IR/IRBuilderTest.cpp
+++ b/llvm/unittests/IR/IRBuilderTest.cpp
@@ -17,6 +17,7 @@
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/NoFolder.h"
+#include "llvm/IR/Verifier.h"
#include "gtest/gtest.h"
using namespace llvm;
@@ -303,8 +304,8 @@ TEST_F(IRBuilderTest, DIBuilder) {
0, true, nullptr);
auto BadScope = DIB.createLexicalBlockFile(BarSP, File, 0);
I->setDebugLoc(DebugLoc::get(2, 0, BadScope));
- EXPECT_FALSE(SP.Verify());
DIB.finalize();
+ EXPECT_TRUE(verifyModule(*M));
}
OpenPOWER on IntegriCloud