Index: include/clang/Driver/SanitizerArgs.h =================================================================== --- include/clang/Driver/SanitizerArgs.h +++ include/clang/Driver/SanitizerArgs.h @@ -10,6 +10,7 @@ #define LLVM_CLANG_DRIVER_SANITIZERARGS_H #include "clang/Basic/Sanitizers.h" +#include "clang/Driver/Types.h" #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" #include @@ -54,8 +55,8 @@ bool requiresPIE() const; bool needsUnwindTables() const; bool linkCXXRuntimes() const { return LinkCXXRuntimes; } - void addArgs(const llvm::opt::ArgList &Args, - llvm::opt::ArgStringList &CmdArgs) const; + void addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs, types::ID InputType) const; private: void clear(); Index: lib/Driver/SanitizerArgs.cpp =================================================================== --- lib/Driver/SanitizerArgs.cpp +++ lib/Driver/SanitizerArgs.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// #include "clang/Driver/SanitizerArgs.h" +#include "Tools.h" #include "clang/Basic/Sanitizers.h" #include "clang/Driver/Driver.h" #include "clang/Driver/DriverDiagnostic.h" @@ -533,8 +534,9 @@ return Res; } -void SanitizerArgs::addArgs(const llvm::opt::ArgList &Args, - llvm::opt::ArgStringList &CmdArgs) const { +void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs, + types::ID InputType) const { if (Sanitizers.empty()) return; CmdArgs.push_back(Args.MakeArgString("-fsanitize=" + toString(Sanitizers))); @@ -581,6 +583,17 @@ // affect compilation. if (Sanitizers.has(Memory) || Sanitizers.has(Address)) CmdArgs.push_back(Args.MakeArgString("-fno-assume-sane-operator-new")); + + if (TC.getTriple().isOSWindows() && needsUbsanRt()) { + // Instruct the code generator to embed linker directives in the object file + // that cause the required runtime libraries to be linked. + CmdArgs.push_back(Args.MakeArgString( + "--dependent-lib=" + tools::getCompilerRT(TC, "ubsan_standalone"))); + if (types::isCXX(InputType)) + CmdArgs.push_back( + Args.MakeArgString("--dependent-lib=" + + tools::getCompilerRT(TC, "ubsan_standalone_cxx"))); + } } SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A, Index: lib/Driver/Tools.h =================================================================== --- lib/Driver/Tools.h +++ lib/Driver/Tools.h @@ -37,6 +37,9 @@ using llvm::opt::ArgStringList; +SmallString<128> getCompilerRT(const ToolChain &TC, StringRef Component, + bool Shared = false); + /// \brief Clang compiler tool. class LLVM_LIBRARY_VISIBILITY Clang : public Tool { public: Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -2231,10 +2231,6 @@ // Until ARM libraries are build separately, we have them all in one library static StringRef getArchNameForCompilerRTLib(const ToolChain &TC) { - // FIXME: handle 64-bit - if (TC.getTriple().isOSWindows() && - !TC.getTriple().isWindowsItaniumEnvironment()) - return "i386"; if (TC.getArch() == llvm::Triple::arm || TC.getArch() == llvm::Triple::armeb) return "arm"; return TC.getArchName(); @@ -2251,8 +2247,8 @@ return Res; } -static SmallString<128> getCompilerRT(const ToolChain &TC, StringRef Component, - bool Shared = false) { +SmallString<128> tools::getCompilerRT(const ToolChain &TC, StringRef Component, + bool Shared) { const char *Env = TC.getTriple().getEnvironment() == llvm::Triple::Android ? "-android" : ""; @@ -3927,7 +3923,7 @@ } const SanitizerArgs &Sanitize = getToolChain().getSanitizerArgs(); - Sanitize.addArgs(Args, CmdArgs); + Sanitize.addArgs(getToolChain(), Args, CmdArgs, InputType); // Report an error for -faltivec on anything other than PowerPC. if (const Arg *A = Args.getLastArg(options::OPT_faltivec)) { Index: test/Driver/cl-link.c =================================================================== --- test/Driver/cl-link.c +++ test/Driver/cl-link.c @@ -11,7 +11,7 @@ // LINK: "bar" // LINK: "baz" -// RUN: %clang_cl /Tc%s -### -fsanitize=address 2>&1 | FileCheck --check-prefix=ASAN %s +// RUN: %clang_cl -m32 /Tc%s -### -fsanitize=address 2>&1 | FileCheck --check-prefix=ASAN %s // ASAN: link.exe // ASAN: "-debug" // ASAN: "-incremental:no" @@ -19,7 +19,7 @@ // ASAN: "{{.*}}clang_rt.asan_cxx-i386.lib" // ASAN: "{{.*}}cl-link{{.*}}.obj" -// RUN: %clang_cl /MD /Tc%s -### -fsanitize=address 2>&1 | FileCheck --check-prefix=ASAN-MD %s +// RUN: %clang_cl -m32 /MD /Tc%s -### -fsanitize=address 2>&1 | FileCheck --check-prefix=ASAN-MD %s // ASAN-MD: link.exe // ASAN-MD: "-debug" // ASAN-MD: "-incremental:no" @@ -33,8 +33,8 @@ // DLL: link.exe // "-dll" -// RUN: %clang_cl /LD /Tc%s -### -fsanitize=address 2>&1 | FileCheck --check-prefix=ASAN-DLL %s -// RUN: %clang_cl /LDd /Tc%s -### -fsanitize=address 2>&1 | FileCheck --check-prefix=ASAN-DLL %s +// RUN: %clang_cl -m32 /LD /Tc%s -### -fsanitize=address 2>&1 | FileCheck --check-prefix=ASAN-DLL %s +// RUN: %clang_cl -m32 /LDd /Tc%s -### -fsanitize=address 2>&1 | FileCheck --check-prefix=ASAN-DLL %s // ASAN-DLL: link.exe // ASAN-DLL: "-dll" // ASAN-DLL: "-debug" Index: test/Driver/fsanitize.c =================================================================== --- test/Driver/fsanitize.c +++ test/Driver/fsanitize.c @@ -16,6 +16,15 @@ // RUN: %clang -target i386-unknown-openbsd -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-OPENBSD // CHECK-UNDEFINED-OPENBSD: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|object-size|float-cast-overflow|array-bounds|enum|bool|returns-nonnull-attribute|nonnull-attribute),?){17}"}} +// RUN: %clang -target i386-pc-win32 -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-WIN --check-prefix=CHECK-UNDEFINED-WIN32 +// RUN: %clang -target i386-pc-win32 -fsanitize=undefined -x c++ %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-WIN --check-prefix=CHECK-UNDEFINED-WIN32 --check-prefix=CHECK-UNDEFINED-WIN-CXX +// RUN: %clang -target x86_64-pc-win32 -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-WIN --check-prefix=CHECK-UNDEFINED-WIN64 +// RUN: %clang -target x86_64-pc-win32 -fsanitize=undefined -x c++ %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-WIN --check-prefix=CHECK-UNDEFINED-WIN64 --check-prefix=CHECK-UNDEFINED-WIN-CXX +// CHECK-UNDEFINED-WIN: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|object-size|float-cast-overflow|array-bounds|enum|bool|returns-nonnull-attribute|nonnull-attribute),?){17}"}} +// CHECK-UNDEFINED-WIN32-SAME: "--dependent-lib={{[^"]*}}ubsan_standalone-i386.lib" +// CHECK-UNDEFINED-WIN64-SAME: "--dependent-lib={{[^"]*}}ubsan_standalone-x86_64.lib" +// CHECK-UNDEFINED-WIN-CXX-SAME: "--dependent-lib={{[^"]*}}ubsan_standalone_cxx{{[^"]*}}.lib" + // RUN: %clang -target x86_64-linux-gnu -fsanitize=integer %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-INTEGER // CHECK-INTEGER: "-fsanitize={{((signed-integer-overflow|unsigned-integer-overflow|integer-divide-by-zero|shift-base|shift-exponent),?){5}"}}