Index: lib/CodeGen/BackendUtil.cpp =================================================================== --- lib/CodeGen/BackendUtil.cpp +++ lib/CodeGen/BackendUtil.cpp @@ -53,6 +53,7 @@ #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h" #include "llvm/Transforms/InstCombine/InstCombine.h" #include "llvm/Transforms/Instrumentation.h" +#include "llvm/Transforms/Instrumentation/AddressSanitizer.h" #include "llvm/Transforms/Instrumentation/BoundsChecking.h" #include "llvm/Transforms/Instrumentation/GCOVProfiler.h" #include "llvm/Transforms/Instrumentation/MemorySanitizer.h" @@ -243,15 +244,15 @@ bool UseGlobalsGC = asanUseGlobalsGC(T, CGOpts); PM.add(createAddressSanitizerFunctionPass(/*CompileKernel*/ false, Recover, UseAfterScope)); - PM.add(createAddressSanitizerModulePass(/*CompileKernel*/ false, Recover, - UseGlobalsGC, UseOdrIndicator)); + PM.add(createModuleAddressSanitizerLegacyPassPass( + /*CompileKernel*/ false, Recover, UseGlobalsGC, UseOdrIndicator)); } static void addKernelAddressSanitizerPasses(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) { PM.add(createAddressSanitizerFunctionPass( /*CompileKernel*/ true, /*Recover*/ true, /*UseAfterScope*/ false)); - PM.add(createAddressSanitizerModulePass( + PM.add(createModuleAddressSanitizerLegacyPassPass( /*CompileKernel*/ true, /*Recover*/ true, /*UseGlobalsGC*/ true, /*UseOdrIndicator*/ false)); } @@ -917,6 +918,22 @@ } } +void addSanitizersAtO0(ModulePassManager &MPM, const Triple &TargetTriple, + const LangOptions &LangOpts, + const CodeGenOptions &CodeGenOpts) { + if (LangOpts.Sanitize.has(SanitizerKind::Address)) { + MPM.addPass(RequireAnalysisPass()); + bool Recover = CodeGenOpts.SanitizeRecover.has(SanitizerKind::Address); + MPM.addPass(createModuleToFunctionPassAdaptor( + AddressSanitizerPass(/*CompileKernel=*/false, Recover, + CodeGenOpts.SanitizeAddressUseAfterScope))); + bool ModuleUseAfterScope = asanUseGlobalsGC(TargetTriple, CodeGenOpts); + MPM.addPass(ModuleAddressSanitizerPass( + /*CompileKernel=*/false, Recover, ModuleUseAfterScope, + CodeGenOpts.SanitizeAddressUseOdrIndicator)); + } +} + /// A clean version of `EmitAssembly` that uses the new pass manager. /// /// Not all features are currently supported in this system, but where @@ -1043,6 +1060,26 @@ [](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) { FPM.addPass(ThreadSanitizerPass()); }); + if (LangOpts.Sanitize.has(SanitizerKind::Address)) { + PB.registerPipelineStartEPCallback([&](ModulePassManager &MPM) { + MPM.addPass( + RequireAnalysisPass()); + }); + bool Recover = CodeGenOpts.SanitizeRecover.has(SanitizerKind::Address); + PB.registerOptimizerLastEPCallback( + [&](FunctionPassManager &FPM, + PassBuilder::OptimizationLevel Level) { + FPM.addPass(AddressSanitizerPass( + /*CompileKernel=*/false, Recover, + CodeGenOpts.SanitizeAddressUseAfterScope)); + }); + bool ModuleUseAfterScope = asanUseGlobalsGC(TargetTriple, CodeGenOpts); + PB.registerPipelineStartEPCallback([&](ModulePassManager &MPM) { + MPM.addPass(ModuleAddressSanitizerPass( + /*CompileKernel=*/false, Recover, ModuleUseAfterScope, + CodeGenOpts.SanitizeAddressUseOdrIndicator)); + }); + } if (Optional Options = getGCOVOptions(CodeGenOpts)) PB.registerPipelineStartEPCallback([Options](ModulePassManager &MPM) { MPM.addPass(GCOVProfilerPass(*Options)); @@ -1063,6 +1100,9 @@ CodeGenOpts.DebugPassManager); } } + + if (CodeGenOpts.OptimizationLevel == 0) + addSanitizersAtO0(MPM, TargetTriple, LangOpts, CodeGenOpts); } // FIXME: We still use the legacy pass manager to do code generation. We Index: test/CodeGen/asan-new-pm.ll =================================================================== --- test/CodeGen/asan-new-pm.ll +++ test/CodeGen/asan-new-pm.ll @@ -0,0 +1,28 @@ +; Test that ASan runs with the new pass manager +; RUN: %clang_cc1 -S -emit-llvm -o - -fexperimental-new-pass-manager -fsanitize=address %s | FileCheck %s --check-prefixes=CHECK,LTO,THINLTO +; RUN: %clang_cc1 -S -emit-llvm -o - -fexperimental-new-pass-manager -fsanitize=address -flto %s | FileCheck %s --check-prefixes=CHECK,LTO +; RUN: %clang_cc1 -S -emit-llvm -o - -fexperimental-new-pass-manager -fsanitize=address -flto=thin %s | FileCheck %s --check-prefixes=CHECK,THINLTO +; RUN: %clang_cc1 -S -emit-llvm -o - -O1 -fexperimental-new-pass-manager -fsanitize=address %s | FileCheck %s --check-prefixes=CHECK,LTO,THINLTO +; RUN: %clang_cc1 -S -emit-llvm -o - -O1 -fexperimental-new-pass-manager -fsanitize=address -flto %s | FileCheck %s --check-prefixes=CHECK,LTO +; RUN: %clang_cc1 -S -emit-llvm -o - -O1 -fexperimental-new-pass-manager -fsanitize=address -flto=thin %s | FileCheck %s --check-prefixes=CHECK,THINLTO + +; DAG-CHECK: @llvm.global_ctors = {{.*}}@asan.module_ctor + +define i32 @test_load(i32* %a) sanitize_address { +entry: + %tmp1 = load i32, i32* %a, align 4 + ret i32 %tmp1 +} + +; CHECK: __asan_init + +; DAG-CHECK: define internal void @asan.module_ctor() { +; CHECK: {{.*}} call void @__asan_init() +; CHECK: {{.*}} call void @__asan_version_mismatch_check_v8() +; CHECK: ret void +; CHECK: } + +; DAG-CHECK: __asan_version_mismatch_check_v8 + +; This is not used in ThinLTO +; DAG-LTO: __asan_report_load4