diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp --- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -556,6 +556,21 @@ } } +// For a ret instruction followed by a musttail call, we cannot insert anything +// in between and have to return the new insertion point as the call inst. +static Instruction *adjustForMusttailCall(Instruction *I) { + ReturnInst *RI = dyn_cast(I); + if (!RI) + return I; + Instruction *Prev = RI->getPrevNode(); + if (BitCastInst *BCI = dyn_cast_or_null(Prev)) + Prev = BCI->getPrevNode(); + if (CallInst *CI = dyn_cast_or_null(Prev)) + if (CI->isMustTailCall()) + return CI; + return RI; +} + namespace { /// Module analysis for getting various metadata about the module. @@ -999,10 +1014,11 @@ // Unpoison dynamic allocas redzones. void unpoisonDynamicAllocas() { - for (auto &Ret : RetVec) - unpoisonDynamicAllocasBeforeInst(Ret, DynamicAllocaLayout); + for (Instruction *Ret : RetVec) + unpoisonDynamicAllocasBeforeInst(adjustForMusttailCall(Ret), + DynamicAllocaLayout); - for (auto &StackRestoreInst : StackRestoreVec) + for (Instruction *StackRestoreInst : StackRestoreVec) unpoisonDynamicAllocasBeforeInst(StackRestoreInst, StackRestoreInst->getOperand(0)); } @@ -3303,7 +3319,8 @@ SmallVector ShadowAfterReturn; // (Un)poison the stack before all ret instructions. - for (auto Ret : RetVec) { + for (Instruction *Ret : RetVec) { + Ret = adjustForMusttailCall(Ret); IRBuilder<> IRBRet(Ret); // Mark the current frame as retired. IRBRet.CreateStore(ConstantInt::get(IntptrTy, kRetiredStackFrameMagic),