public:
DataFlowSanitizer(const std::vector<std::string> &ABIListFiles);
- bool runImpl(Module &M, ModuleAnalysisManager *AM = nullptr);
+ bool runImpl(Module &M,
+ llvm::function_ref<TargetLibraryInfo &(Function &)> GetTLI);
};
struct DFSanFunction {
DominatorTree DT;
bool IsNativeABI;
bool IsForceZeroLabels;
- TargetLibraryInfo *TLI = nullptr;
+ TargetLibraryInfo &TLI;
AllocaInst *LabelReturnAlloca = nullptr;
AllocaInst *OriginReturnAlloca = nullptr;
DenseMap<Value *, Value *> ValShadowMap;
DenseMap<Value *, std::set<Value *>> ShadowElements;
DFSanFunction(DataFlowSanitizer &DFS, Function *F, bool IsNativeABI,
- bool IsForceZeroLabels, TargetLibraryInfo *TLI)
+ bool IsForceZeroLabels, TargetLibraryInfo &TLI)
: DFS(DFS), F(F), IsNativeABI(IsNativeABI),
IsForceZeroLabels(IsForceZeroLabels), TLI(TLI) {
DT.recalculate(*F);
});
}
-bool DataFlowSanitizer::runImpl(Module &M, ModuleAnalysisManager *AM) {
+bool DataFlowSanitizer::runImpl(
+ Module &M, llvm::function_ref<TargetLibraryInfo &(Function &)> GetTLI) {
initializeModule(M);
if (ABIList.isIn(M, "skip"))
removeUnreachableBlocks(*F);
- // TODO: Use reference instead of pointer, TLI should not be optional.
- // Using a pointer here is a hack so that DFSan run from legacy
- // pass manager can skip getting the TargetLibraryAnalysis.
- TargetLibraryInfo *TLI = nullptr;
- if (AM) {
- auto &FAM =
- AM->getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
- TLI = &FAM.getResult<TargetLibraryAnalysis>(*F);
- }
-
DFSanFunction DFSF(*this, F, FnsWithNativeABI.count(F),
- FnsWithForceZeroLabel.count(F), TLI);
+ FnsWithForceZeroLabel.count(F), GetTLI(*F));
// DFSanVisitor may create new basic blocks, which confuses df_iterator.
// Build a copy of the list before iterating over it.
return;
LibFunc LF;
- if (DFSF.TLI->getLibFunc(CB, LF)) {
+ if (DFSF.TLI.getLibFunc(CB, LF)) {
// libatomic.a functions need to have special handling because there isn't
// a good way to intercept them or compile the library with
// instrumentation.
const std::vector<std::string> &ABIListFiles = std::vector<std::string>())
: ModulePass(ID), ABIListFiles(ABIListFiles) {}
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.addRequired<TargetLibraryInfoWrapperPass>();
+ }
+
bool runOnModule(Module &M) override {
- return DataFlowSanitizer(ABIListFiles).runImpl(M);
+ return DataFlowSanitizer(ABIListFiles)
+ .runImpl(M, [&](Function &F) -> TargetLibraryInfo & {
+ return getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
+ });
}
};
} // namespace
char DataFlowSanitizerLegacyPass::ID;
-INITIALIZE_PASS(DataFlowSanitizerLegacyPass, "dfsan",
- "DataFlowSanitizer: dynamic data flow analysis.", false, false)
+INITIALIZE_PASS_BEGIN(DataFlowSanitizerLegacyPass, "dfsan",
+ "DataFlowSanitizer: dynamic data flow analysis.", false,
+ false)
+INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
+INITIALIZE_PASS_END(DataFlowSanitizerLegacyPass, "dfsan",
+ "DataFlowSanitizer: dynamic data flow analysis.", false,
+ false)
ModulePass *llvm::createDataFlowSanitizerLegacyPassPass(
const std::vector<std::string> &ABIListFiles) {
PreservedAnalyses DataFlowSanitizerPass::run(Module &M,
ModuleAnalysisManager &AM) {
- if (!DataFlowSanitizer(ABIListFiles).runImpl(M, &AM))
+ auto GetTLI = [&](Function &F) -> TargetLibraryInfo & {
+ auto &FAM =
+ AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
+ return FAM.getResult<TargetLibraryAnalysis>(F);
+ };
+ if (!DataFlowSanitizer(ABIListFiles).runImpl(M, GetTLI))
return PreservedAnalyses::all();
PreservedAnalyses PA = PreservedAnalyses::none();