Index: lib/Driver/ToolChains.cpp =================================================================== --- lib/Driver/ToolChains.cpp +++ lib/Driver/ToolChains.cpp @@ -368,47 +368,34 @@ const SanitizerArgs &Sanitize = getSanitizerArgs(); - // Add Ubsan runtime library, if required. - if (Sanitize.needsUbsanRt()) { - // FIXME: Move this check to SanitizerArgs::filterUnsupportedKinds. - if (isTargetIOSBased()) { - getDriver().Diag(diag::err_drv_clang_unsupported_per_platform) - << "-fsanitize=undefined"; - } else { - assert(isTargetMacOS() && "unexpected non OS X target"); - AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.ubsan_osx.a", true); - - // The Ubsan runtime library requires C++. - AddCXXStdlibLibArgs(Args, CmdArgs); - } - } - - // Add ASAN runtime library, if required. Dynamic libraries and bundles - // should not be linked with the runtime library. - if (Sanitize.needsAsanRt()) { - // FIXME: Move this check to SanitizerArgs::filterUnsupportedKinds. - if (isTargetIPhoneOS()) { - getDriver().Diag(diag::err_drv_clang_unsupported_per_platform) - << "-fsanitize=address"; + // Add ASan/UBSan runtime libraries, if required. + if (Sanitize.needsAsanRt() || Sanitize.needsUbsanRt()) { + // For now we can't use ASan and UBSan together on Mac (PR21112). + if (Sanitize.needsAsanRt() && Sanitize.needsUbsanRt()) { + getDriver().Diag(diag::err_drv_argument_not_allowed_with) + << "-fsanitize=address" + << "-fsanitize=undefined"; + } else if (!isTargetMacOS() && !isTargetIOSSimulator()) { + // FIXME: Move this check to SanitizerArgs::filterUnsupportedKinds. + StringRef Arg = Sanitize.needsAsanRt() ? "-fsanitize=address" + : "-fsanitize=undefined"; + getDriver().Diag(diag::err_drv_clang_unsupported_per_platform) << Arg; } else { if (!Args.hasArg(options::OPT_dynamiclib) && !Args.hasArg(options::OPT_bundle)) { - // The ASAN runtime library requires C++. + // Sanitizer runtime libraries requires C++. AddCXXStdlibLibArgs(Args, CmdArgs); + // Add explicit dependcy on -lc++abi, as -lc++ doesn't re-export + // all RTTI-related symbols that UBSan uses. + if (Sanitize.needsUbsanRt()) + CmdArgs.push_back("-lc++abi"); } - if (isTargetMacOS()) { - AddLinkRuntimeLib(Args, CmdArgs, - "libclang_rt.asan_osx_dynamic.dylib", - /*AlwaysLink*/ true, /*IsEmbedded*/ false, - /*AddRPath*/ true); - } else { - if (isTargetIOSSimulator()) { - AddLinkRuntimeLib(Args, CmdArgs, - "libclang_rt.asan_iossim_dynamic.dylib", - /*AlwaysLink*/ true, /*IsEmbedded*/ false, - /*AddRPath*/ true); - } - } + StringRef OS = isTargetMacOS() ? "osx" : "iossim"; + StringRef Sanitizer = Sanitize.needsAsanRt() ? "asan" : "ubsan"; + AddLinkRuntimeLib(Args, CmdArgs, (Twine("libclang_rt.") + Sanitizer + + "_" + OS + "_dynamic.dylib").str(), + /*AlwaysLink*/ true, /*IsEmbedded*/ false, + /*AddRPath*/ true); } } Index: runtime/compiler-rt/Makefile =================================================================== --- runtime/compiler-rt/Makefile +++ runtime/compiler-rt/Makefile @@ -79,7 +79,7 @@ eprintf.a 10.4.a osx.a cc_kext.a \ asan_osx_dynamic.dylib \ profile_osx.a \ - ubsan_osx.a + ubsan_osx_dynamic.dylib IOS_SDK := $(shell xcrun --show-sdk-path -sdk iphoneos 2> /dev/null) IOSSIM_SDK := $(shell xcrun --show-sdk-path -sdk iphonesimulator 2> /dev/null) @@ -93,7 +93,8 @@ endif ifneq ($(IOSSIM_SDK),) -RuntimeLibrary.darwin.Configs += asan_iossim_dynamic.dylib +RuntimeLibrary.darwin.Configs += asan_iossim_dynamic.dylib \ + ubsan_iossim_dynamic.dylib endif RuntimeLibrary.macho_embedded.Configs := \ Index: test/Driver/darwin-sanitizer-ld.c =================================================================== --- test/Driver/darwin-sanitizer-ld.c +++ test/Driver/darwin-sanitizer-ld.c @@ -35,8 +35,10 @@ // RUN: | FileCheck --check-prefix=CHECK-UBSAN %s // CHECK-UBSAN: "{{.*}}ld{{(.exe)?}}" -// CHECK-UBSAN: libclang_rt.ubsan_osx.a" // CHECK-UBSAN: stdc++ +// CHECK-UBSAN: libclang_rt.ubsan_osx_dynamic.dylib" +// CHECK-UBSAN: "-rpath" "@executable_path" +// CHECK-UBSAN: "-rpath" "{{.*}}lib{{.*}}darwin" // RUN: %clang -no-canonical-prefixes -### -target x86_64-darwin \ // RUN: -fsanitize=bounds -fsanitize-undefined-trap-on-error \ @@ -52,7 +54,9 @@ // CHECK-DYN-UBSAN: "{{.*}}ld{{(.exe)?}}" // CHECK-DYN-UBSAN: "-dylib" -// CHECK-DYN-UBSAN: libclang_rt.ubsan_osx.a +// CHECK-DYN-UBSAN: libclang_rt.ubsan_osx_dynamic.dylib" +// CHECK-DYN-UBSAN: "-rpath" "@executable_path" +// CHECK-DYN-UBSAN: "-rpath" "{{.*}}lib{{.*}}darwin" // RUN: %clang -no-canonical-prefixes -### -target x86_64-darwin \ // RUN: -fsanitize=bounds -fsanitize-undefined-trap-on-error \ @@ -60,4 +64,10 @@ // RUN: | FileCheck --check-prefix=CHECK-DYN-BOUNDS %s // CHECK-DYN-BOUNDS: "{{.*}}ld{{(.exe)?}}" -// CHECK-DYN-BOUNDS-NOT: libclang_rt.ubsan_osx.a +// CHECK-DYN-BOUNDS-NOT: ubsan_osx + +// RUN: %clang -no-canonical-prefixes -### -target x86_64-darwin \ +// RUN: -fsanitize=address,undefined %s -o %t.o 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-ASAN-UBSAN %s + +// CHECK-ASAN-UBSAN: error: invalid argument '-fsanitize=address' not allowed with '-fsanitize=undefined'