Index: cfe/trunk/lib/Driver/ToolChain.cpp =================================================================== --- cfe/trunk/lib/Driver/ToolChain.cpp +++ cfe/trunk/lib/Driver/ToolChain.cpp @@ -367,8 +367,10 @@ TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment(); const char *Prefix = IsITANMSVCWindows ? "" : "lib"; - const char *Suffix = Shared ? (Triple.isOSWindows() ? ".dll" : ".so") + const char *Suffix = Shared ? (Triple.isOSWindows() ? ".lib" : ".so") : (IsITANMSVCWindows ? ".lib" : ".a"); + if (Shared && Triple.isWindowsGNUEnvironment()) + Suffix = ".dll.a"; for (const auto &LibPath : getLibraryPaths()) { SmallString<128> P(LibPath); Index: cfe/trunk/lib/Driver/ToolChains/MinGW.h =================================================================== --- cfe/trunk/lib/Driver/ToolChains/MinGW.h +++ cfe/trunk/lib/Driver/ToolChains/MinGW.h @@ -65,6 +65,8 @@ bool isPIEDefault() const override; bool isPICDefaultForced() const override; + SanitizerMask getSupportedSanitizers() const override; + llvm::ExceptionHandling GetExceptionModel( const llvm::opt::ArgList &Args) const override; Index: cfe/trunk/lib/Driver/ToolChains/MinGW.cpp =================================================================== --- cfe/trunk/lib/Driver/ToolChains/MinGW.cpp +++ cfe/trunk/lib/Driver/ToolChains/MinGW.cpp @@ -14,6 +14,7 @@ #include "clang/Driver/Driver.h" #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Options.h" +#include "clang/Driver/SanitizerArgs.h" #include "llvm/Option/ArgList.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" @@ -95,7 +96,7 @@ const char *LinkingOutput) const { const ToolChain &TC = getToolChain(); const Driver &D = TC.getDriver(); - // const SanitizerArgs &Sanitize = TC.getSanitizerArgs(); + const SanitizerArgs &Sanitize = TC.getSanitizerArgs(); ArgStringList CmdArgs; @@ -187,8 +188,6 @@ TC.AddFilePathLibArgs(Args, CmdArgs); AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA); - // TODO: Add ASan stuff here - // TODO: Add profile stuff here if (TC.ShouldLinkCXXStdlib(Args)) { @@ -231,6 +230,24 @@ if (Args.hasArg(options::OPT_pthread)) CmdArgs.push_back("-lpthread"); + if (Sanitize.needsAsanRt()) { + // MinGW always links against a shared MSVCRT. + CmdArgs.push_back( + TC.getCompilerRTArgString(Args, "asan_dynamic", true)); + CmdArgs.push_back( + TC.getCompilerRTArgString(Args, "asan_dynamic_runtime_thunk")); + CmdArgs.push_back(Args.MakeArgString("--require-defined")); + CmdArgs.push_back(Args.MakeArgString(TC.getArch() == llvm::Triple::x86 + ? "___asan_seh_interceptor" + : "__asan_seh_interceptor")); + // Make sure the linker consider all object files from the dynamic + // runtime thunk. + CmdArgs.push_back(Args.MakeArgString("--whole-archive")); + CmdArgs.push_back(Args.MakeArgString( + TC.getCompilerRT(Args, "asan_dynamic_runtime_thunk"))); + CmdArgs.push_back(Args.MakeArgString("--no-whole-archive")); + } + if (!HasWindowsApp) { // Add system libraries. If linking to libwindowsapp.a, that import // library replaces all these and we shouldn't accidentally try to @@ -407,6 +424,12 @@ return llvm::ExceptionHandling::DwarfCFI; } +SanitizerMask toolchains::MinGW::getSupportedSanitizers() const { + SanitizerMask Res = ToolChain::getSupportedSanitizers(); + Res |= SanitizerKind::Address; + return Res; +} + void toolchains::MinGW::AddCudaIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const { CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args); Index: cfe/trunk/test/Driver/mingw-sanitizers.c =================================================================== --- cfe/trunk/test/Driver/mingw-sanitizers.c +++ cfe/trunk/test/Driver/mingw-sanitizers.c @@ -0,0 +1,11 @@ +// RUN: %clang -target i686-windows-gnu %s -### -fsanitize=address 2>&1 | FileCheck --check-prefix=ASAN-I686 %s +// ASAN-I686: "{{.*}}libclang_rt.asan_dynamic-i386.dll.a" +// ASAN-I686: "{{[^"]*}}libclang_rt.asan_dynamic_runtime_thunk-i386.a" +// ASAN-I686: "--require-defined" "___asan_seh_interceptor" +// ASAN-I686: "--whole-archive" "{{.*}}libclang_rt.asan_dynamic_runtime_thunk-i386.a" "--no-whole-archive" + +// RUN: %clang -target x86_64-windows-gnu %s -### -fsanitize=address 2>&1 | FileCheck --check-prefix=ASAN-X86_64 %s +// ASAN-X86_64: "{{.*}}libclang_rt.asan_dynamic-x86_64.dll.a" +// ASAN-X86_64: "{{[^"]*}}libclang_rt.asan_dynamic_runtime_thunk-x86_64.a" +// ASAN-X86_64: "--require-defined" "__asan_seh_interceptor" +// ASAN-X86_64: "--whole-archive" "{{.*}}libclang_rt.asan_dynamic_runtime_thunk-x86_64.a" "--no-whole-archive"