aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms/Utils/Local.cpp
diff options
context:
space:
mode:
authorAlexey Samsonov <samsonov@google.com>2012-12-12 14:31:53 +0000
committerAlexey Samsonov <samsonov@google.com>2012-12-12 14:31:53 +0000
commit1afbb517965e29b07cb42e2335d5eadd87de6535 (patch)
tree4ca2a2f4c8eecd1ca7daeebe22eb5ca9a4355c81 /lib/Transforms/Utils/Local.cpp
parentcd5eb17be65627a1bf4b1e87b0a79573ba23463d (diff)
downloadexternal_llvm-1afbb517965e29b07cb42e2335d5eadd87de6535.zip
external_llvm-1afbb517965e29b07cb42e2335d5eadd87de6535.tar.gz
external_llvm-1afbb517965e29b07cb42e2335d5eadd87de6535.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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@169984 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Utils/Local.cpp')
-rw-r--r--lib/Transforms/Utils/Local.cpp35
1 files changed, 35 insertions, 0 deletions
diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp
index 0e56817..58d973a 100644
--- a/lib/Transforms/Utils/Local.cpp
+++ b/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;
+}