summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorAdrian Prantl <aprantl@apple.com>2017-02-21 19:03:15 +0000
committerAdrian Prantl <aprantl@apple.com>2017-02-21 19:03:15 +0000
commit11b2d7dad8bad9d6ca739e82d9364f34eb2a3d49 (patch)
treeb25d0f65df552cea0da841a14799b2cbfa584e7a /llvm/lib
parent5d534b6a11d6428d173279e5155b4f966dab1be7 (diff)
downloadbcm5719-llvm-11b2d7dad8bad9d6ca739e82d9364f34eb2a3d49.tar.gz
bcm5719-llvm-11b2d7dad8bad9d6ca739e82d9364f34eb2a3d49.zip
Teach the IR verifier to reject conflicting debug info for function arguments.
Conflicting debug info for function arguments causes hard-to-debug assertions in the DWARF backend, so the Verifier should reject it. For performance reasons this only checks function arguments from non-inlined debug intrinsics for now. rdar://problem/30520286 llvm-svn: 295749
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/IR/Verifier.cpp38
1 files changed, 38 insertions, 0 deletions
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 7d0bfd7270c..4dd18797a95 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -297,6 +297,9 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
// constant expressions, we can arrive at a particular user many times.
SmallPtrSet<const Value *, 32> GlobalValueVisited;
+ // Keeps track of duplicate function argument debug info.
+ SmallVector<const DILocalVariable *, 16> DebugFnArgs;
+
TBAAVerifier TBAAVerifyHelper;
void checkAtomicMemAccessSize(Type *Ty, const Instruction *I);
@@ -498,6 +501,7 @@ private:
void verifySiblingFuncletUnwinds();
void verifyFragmentExpression(const DbgInfoIntrinsic &I);
+ void verifyFnArgs(const DbgInfoIntrinsic &I);
/// Module-level debug info verification...
void verifyCompileUnits();
@@ -1946,6 +1950,8 @@ void Verifier::verifySiblingFuncletUnwinds() {
// visitFunction - Verify that a function is ok.
//
void Verifier::visitFunction(const Function &F) {
+ DebugFnArgs.clear();
+
visitGlobalValue(F);
// Check function arguments.
@@ -4348,6 +4354,8 @@ void Verifier::visitDbgIntrinsic(StringRef Kind, DbgIntrinsicTy &DII) {
" variable and !dbg attachment",
&DII, BB, F, Var, Var->getScope()->getSubprogram(), Loc,
Loc->getScope()->getSubprogram());
+
+ verifyFnArgs(DII);
}
static uint64_t getVariableSize(const DILocalVariable &V) {
@@ -4416,6 +4424,36 @@ void Verifier::verifyFragmentExpression(const DbgInfoIntrinsic &I) {
AssertDI(FragSize != VarSize, "fragment covers entire variable", &I, V, E);
}
+void Verifier::verifyFnArgs(const DbgInfoIntrinsic &I) {
+ DILocalVariable *Var;
+ if (auto *DV = dyn_cast<DbgValueInst>(&I)) {
+ // For performance reasons only check non-inlined ones.
+ if (DV->getDebugLoc()->getInlinedAt())
+ return;
+ Var = DV->getVariable();
+ } else {
+ auto *DD = cast<DbgDeclareInst>(&I);
+ if (DD->getDebugLoc()->getInlinedAt())
+ return;
+ Var = DD->getVariable();
+ }
+ AssertDI(Var, "dbg intrinsic without variable");
+
+ unsigned ArgNo = Var->getArg();
+ if (!ArgNo)
+ return;
+
+ // Verify there are no duplicate function argument debug info entries.
+ // These will cause hard-to-debug assertions in the DWARF backend.
+ if (DebugFnArgs.size() < ArgNo)
+ DebugFnArgs.resize(ArgNo, nullptr);
+
+ auto *Prev = DebugFnArgs[ArgNo - 1];
+ DebugFnArgs[ArgNo - 1] = Var;
+ AssertDI(!Prev || (Prev == Var), "conflicting debug info for argument", &I,
+ Prev, Var);
+}
+
void Verifier::verifyCompileUnits() {
auto *CUs = M.getNamedMetadata("llvm.dbg.cu");
SmallPtrSet<const Metadata *, 2> Listed;
OpenPOWER on IntegriCloud