diff options
| author | Alexey Samsonov <samsonov@google.com> | 2012-12-12 14:31:53 +0000 |
|---|---|---|
| committer | Alexey Samsonov <samsonov@google.com> | 2012-12-12 14:31:53 +0000 |
| commit | 3d43b63a6e9668b90c6fb01f2255e4b42d45e75e (patch) | |
| tree | 61944e9be784e785370dccdaa3e87a283e97ac4d /llvm/lib/Transforms/Utils/Local.cpp | |
| parent | 9bd2e1bacc5455ebcf93aad3cf564ff88cabca96 (diff) | |
| download | llvm-3d43b63a6e9668b90c6fb01f2255e4b42d45e75e.zip llvm-3d43b63a6e9668b90c6fb01f2255e4b42d45e75e.tar.gz llvm-3d43b63a6e9668b90c6fb01f2255e4b42d45e75e.tar.bz2 | |
Improve debug info generated with enabled AddressSanitizer.
When ASan replaces <alloca instruction> with
<offset into a common large alloca>, it should also patch
llvm.dbg.declare calls and replace debug info descriptors to mark
that we've replaced alloca with a value that stores an address
of the user variable, not the user variable itself.
See PR11818 for more context.
llvm-svn: 169984
Diffstat (limited to 'llvm/lib/Transforms/Utils/Local.cpp')
| -rw-r--r-- | llvm/lib/Transforms/Utils/Local.cpp | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index 0e56817..58d973a6 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -928,3 +928,38 @@ DbgDeclareInst *llvm::FindAllocaDbgDeclare(Value *V) { return 0; } + +bool llvm::replaceDbgDeclareForAlloca(AllocaInst *AI, Value *NewAllocaAddress, + DIBuilder &Builder) { + DbgDeclareInst *DDI = FindAllocaDbgDeclare(AI); + if (!DDI) + return false; + DIVariable DIVar(DDI->getVariable()); + if (!DIVar.Verify()) + return false; + + // Create a copy of the original DIDescriptor for user variable, appending + // "deref" operation to a list of address elements, as new llvm.dbg.declare + // will take a value storing address of the memory for variable, not + // alloca itself. + Type *Int64Ty = Type::getInt64Ty(AI->getContext()); + SmallVector<Value*, 4> NewDIVarAddress; + if (DIVar.hasComplexAddress()) { + for (unsigned i = 0, n = DIVar.getNumAddrElements(); i < n; ++i) { + NewDIVarAddress.push_back( + ConstantInt::get(Int64Ty, DIVar.getAddrElement(i))); + } + } + NewDIVarAddress.push_back(ConstantInt::get(Int64Ty, DIBuilder::OpDeref)); + DIVariable NewDIVar = Builder.createComplexVariable( + DIVar.getTag(), DIVar.getContext(), DIVar.getName(), + DIVar.getFile(), DIVar.getLineNumber(), DIVar.getType(), + NewDIVarAddress, DIVar.getArgNumber()); + + // Insert llvm.dbg.declare in the same basic block as the original alloca, + // and remove old llvm.dbg.declare. + BasicBlock *BB = AI->getParent(); + Builder.insertDeclare(NewAllocaAddress, NewDIVar, BB); + DDI->eraseFromParent(); + return true; +} |
