DataFlowSanitizer: fix a use-after-free. Spotted by libgmalloc.
[oota-llvm.git] / lib / Transforms / Instrumentation / DataFlowSanitizer.cpp
index 1cfbba719977e15f0f89841850987b94fd4118f2..af227d27d9208e33113675c3094c7734317842d0 100644 (file)
@@ -59,6 +59,7 @@
 #include "llvm/Pass.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
+#include "llvm/Transforms/Utils/Local.h"
 #include "llvm/Transforms/Utils/SpecialCaseList.h"
 #include <iterator>
 
@@ -128,7 +129,7 @@ class DataFlowSanitizer : public ModulePass {
   Constant *DFSanUnionFn;
   Constant *DFSanUnionLoadFn;
   MDNode *ColdCallWeights;
-  SpecialCaseList Greylist;
+  OwningPtr<SpecialCaseList> Greylist;
   DenseMap<Value *, Function *> UnwrappedFnMap;
 
   Value *getShadowAddress(Value *Addr, Instruction *Pos);
@@ -210,7 +211,7 @@ ModulePass *llvm::createDataFlowSanitizerPass(void *(*getArgTLS)(),
 DataFlowSanitizer::DataFlowSanitizer(void *(*getArgTLS)(),
                                      void *(*getRetValTLS)())
     : ModulePass(ID), GetArgTLSPtr(getArgTLS), GetRetvalTLSPtr(getRetValTLS),
-      Greylist(ClGreylistFile) {}
+      Greylist(SpecialCaseList::createOrDie(ClGreylistFile)) {}
 
 FunctionType *DataFlowSanitizer::getInstrumentedFunctionType(FunctionType *T) {
   llvm::SmallVector<Type *, 4> ArgTypes;
@@ -236,7 +237,7 @@ bool DataFlowSanitizer::doInitialization(Module &M) {
   ShadowPtrTy = PointerType::getUnqual(ShadowTy);
   IntptrTy = DL->getIntPtrType(*Ctx);
   ZeroShadow = ConstantInt::getSigned(ShadowTy, 0);
-  ShadowPtrMask = ConstantInt::getSigned(IntptrTy, ~0x700000000000);
+  ShadowPtrMask = ConstantInt::getSigned(IntptrTy, ~0x700000000000LL);
   ShadowPtrMul = ConstantInt::getSigned(IntptrTy, ShadowWidth / 8);
 
   Type *DFSanUnionArgs[2] = { ShadowTy, ShadowTy };
@@ -268,7 +269,7 @@ bool DataFlowSanitizer::doInitialization(Module &M) {
 
 DataFlowSanitizer::InstrumentedABI
 DataFlowSanitizer::getInstrumentedABI(Function *F) {
-  if (Greylist.isIn(*F))
+  if (Greylist->isIn(*F))
     return IA_MemOnly;
   else
     return getDefaultInstrumentedABI();
@@ -402,6 +403,8 @@ bool DataFlowSanitizer::runOnModule(Module &M) {
     if ((*i)->isDeclaration())
       continue;
 
+    removeUnreachableBlocks(**i);
+
     DFSanFunction DFSF(*this, *i);
 
     // DFSanVisitor may create new basic blocks, which confuses df_iterator.
@@ -419,9 +422,12 @@ bool DataFlowSanitizer::runOnModule(Module &M) {
         // instruction's next pointer and moving the next instruction to the
         // tail block from which we should continue.
         Instruction *Next = Inst->getNextNode();
+        // DFSanVisitor may delete Inst, so keep track of whether it was a
+        // terminator.
+        bool IsTerminator = isa<TerminatorInst>(Inst);
         if (!DFSF.SkipInsts.count(Inst))
           DFSanVisitor(DFSF).visit(Inst);
-        if (isa<TerminatorInst>(Inst))
+        if (IsTerminator)
           break;
         Inst = Next;
       }