Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1528,6 +1528,7 @@ def _language : Separate<["--"], "language">, Alias; def _library_directory_EQ : Joined<["--"], "library-directory=">, Alias; def _library_directory : Separate<["--"], "library-directory">, Alias; +def _link_cxx_sanitizer : Flag<["--"], "link-cxx-sanitizer">; def _no_line_commands : Flag<["--"], "no-line-commands">, Alias

; def _no_standard_includes : Flag<["--"], "no-standard-includes">, Alias; def _no_standard_libraries : Flag<["--"], "no-standard-libraries">, Alias; Index: include/clang/Driver/SanitizerArgs.h =================================================================== --- include/clang/Driver/SanitizerArgs.h +++ include/clang/Driver/SanitizerArgs.h @@ -52,9 +52,9 @@ bool AsanZeroBaseShadow; bool UbsanTrapOnError; bool AsanSharedRuntime; + bool LinkCXXRuntimes; public: - SanitizerArgs(); /// Parses the sanitizer arguments from an argument list. SanitizerArgs(const ToolChain &TC, const llvm::opt::ArgList &Args); @@ -77,6 +77,7 @@ return (Kind & HasZeroBaseShadow) || AsanZeroBaseShadow; } bool needsUnwindTables() const { return Kind & NeedsUnwindTables; } + bool linkCXXRuntimes() const { return LinkCXXRuntimes; } void addArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const; Index: lib/Driver/SanitizerArgs.cpp =================================================================== --- lib/Driver/SanitizerArgs.cpp +++ lib/Driver/SanitizerArgs.cpp @@ -28,10 +28,7 @@ AsanZeroBaseShadow = false; UbsanTrapOnError = false; AsanSharedRuntime = false; -} - -SanitizerArgs::SanitizerArgs() { - clear(); + LinkCXXRuntimes = false; } SanitizerArgs::SanitizerArgs(const ToolChain &TC, @@ -168,6 +165,10 @@ AsanZeroBaseShadow = (TC.getTriple().getEnvironment() == llvm::Triple::Android); } + + // Parse -link-cxx-sanitizer flag. + LinkCXXRuntimes = + Args.hasArg(options::OPT__link_cxx_sanitizer) || D.CCCIsCXX(); } void SanitizerArgs::addArgs(const llvm::opt::ArgList &Args, Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -2272,11 +2272,12 @@ const SanitizerArgs &Sanitize = TC.getSanitizerArgs(); const Driver &D = TC.getDriver(); if (Sanitize.needsUbsanRt()) - addUbsanRT(TC, Args, CmdArgs, D.CCCIsCXX(), - Sanitize.needsAsanRt() || Sanitize.needsTsanRt() || - Sanitize.needsMsanRt() || Sanitize.needsLsanRt()); + addUbsanRT(TC, Args, CmdArgs, Sanitize.linkCXXRuntimes(), + Sanitize.needsAsanRt() || Sanitize.needsTsanRt() || + Sanitize.needsMsanRt() || Sanitize.needsLsanRt()); if (Sanitize.needsAsanRt()) - addAsanRT(TC, Args, CmdArgs, Sanitize.needsSharedAsanRt(), D.CCCIsCXX()); + addAsanRT(TC, Args, CmdArgs, Sanitize.needsSharedAsanRt(), + Sanitize.linkCXXRuntimes()); if (Sanitize.needsTsanRt()) addTsanRT(TC, Args, CmdArgs); if (Sanitize.needsMsanRt()) Index: test/Driver/sanitizer-ld.c =================================================================== --- test/Driver/sanitizer-ld.c +++ test/Driver/sanitizer-ld.c @@ -195,6 +195,14 @@ // CHECK-UBSAN-LINUX: "-lpthread" // CHECK-UBSAN-LINUX-NOT: "-lstdc++" +// RUN: %clang -fsanitize=undefined --link-cxx-sanitizer %s -### -o %t.o 2>&1 \ +// RUN: -target i386-unknown-linux \ +// RUN: --sysroot=%S/Inputs/basic_linux_tree \ +// RUN: | FileCheck --check-prefix=CHECK-UBSAN-LINUX-LINK-CXX %s +// CHECK-UBSAN-LINUX-LINK-CXX-NOT: "-lstdc++" +// CHECK-UBSAN-LINUX-LINK-CXX: "-whole-archive" "{{.*}}libclang_rt.ubsan_cxx-i386.a" "-no-whole-archive" +// CHECK-UBSAN-LINUX-LINK-CXX-NOT: "-lstdc++" + // RUN: %clangxx -fsanitize=undefined %s -### -o %t.o 2>&1 \ // RUN: -target i386-unknown-linux \ // RUN: -resource-dir=%S/Inputs/resource_dir \