diff --git a/compiler-rt/lib/msan/CMakeLists.txt b/compiler-rt/lib/msan/CMakeLists.txt index 596d040a5aa3..de5980e5644b 100644 --- a/compiler-rt/lib/msan/CMakeLists.txt +++ b/compiler-rt/lib/msan/CMakeLists.txt @@ -32,9 +32,11 @@ foreach(arch ${MSAN_SUPPORTED_ARCH}) $ $ $ + $ CFLAGS ${MSAN_RTL_CFLAGS}) add_compiler_rt_runtime(clang_rt.msan_cxx-${arch} ${arch} STATIC SOURCES ${MSAN_RTL_CXX_SOURCES} + $ CFLAGS ${MSAN_RTL_CFLAGS}) add_dependencies(msan clang_rt.msan-${arch} clang_rt.msan_cxx-${arch}) diff --git a/compiler-rt/lib/msan/msan.cc b/compiler-rt/lib/msan/msan.cc index 87a9097550b2..8f741de1180a 100644 --- a/compiler-rt/lib/msan/msan.cc +++ b/compiler-rt/lib/msan/msan.cc @@ -26,6 +26,8 @@ #include "sanitizer_common/sanitizer_stacktrace.h" #include "sanitizer_common/sanitizer_symbolizer.h" #include "sanitizer_common/sanitizer_stackdepot.h" +#include "ubsan/ubsan_flags.h" +#include "ubsan/ubsan_init.h" // ACHTUNG! No system header includes in this file. @@ -133,11 +135,6 @@ static void RegisterMsanFlags(FlagParser *parser, Flags *f) { } static void InitializeFlags() { - Flags *f = flags(); - FlagParser parser; - RegisterMsanFlags(&parser, f); - RegisterCommonFlags(&parser); - SetCommonFlagsDefaults(); { CommonFlags cf; @@ -151,14 +148,35 @@ static void InitializeFlags() { OverrideCommonFlags(cf); } + Flags *f = flags(); f->SetDefaults(); + FlagParser parser; + RegisterMsanFlags(&parser, f); + RegisterCommonFlags(&parser); + +#if MSAN_CONTAINS_UBSAN + __ubsan::Flags *uf = __ubsan::flags(); + uf->SetDefaults(); + + FlagParser ubsan_parser; + __ubsan::RegisterUbsanFlags(&ubsan_parser, uf); + RegisterCommonFlags(&ubsan_parser); +#endif + // Override from user-specified string. if (__msan_default_options) parser.ParseString(__msan_default_options()); +#if MSAN_CONTAINS_UBSAN + const char *ubsan_default_options = __ubsan::MaybeCallUbsanDefaultOptions(); + ubsan_parser.ParseString(ubsan_default_options); +#endif const char *msan_options = GetEnv("MSAN_OPTIONS"); parser.ParseString(msan_options); +#if MSAN_CONTAINS_UBSAN + ubsan_parser.ParseString(GetEnv("UBSAN_OPTIONS")); +#endif VPrintf(1, "MSAN_OPTIONS: %s\n", msan_options ? msan_options : ""); SetVerbosity(common_flags()->verbosity); @@ -392,6 +410,10 @@ void __msan_init() { SetCurrentThread(main_thread); main_thread->ThreadStart(); +#if MSAN_CONTAINS_UBSAN + __ubsan::InitAsPlugin(); +#endif + VPrintf(1, "MemorySanitizer init done\n"); msan_init_is_running = 0; diff --git a/compiler-rt/lib/msan/msan.h b/compiler-rt/lib/msan/msan.h index f5f87dd0a411..2d48e69d7cba 100644 --- a/compiler-rt/lib/msan/msan.h +++ b/compiler-rt/lib/msan/msan.h @@ -20,11 +20,16 @@ #include "sanitizer_common/sanitizer_stacktrace.h" #include "msan_interface_internal.h" #include "msan_flags.h" +#include "ubsan/ubsan_platform.h" #ifndef MSAN_REPLACE_OPERATORS_NEW_AND_DELETE # define MSAN_REPLACE_OPERATORS_NEW_AND_DELETE 1 #endif +#ifndef MSAN_CONTAINS_UBSAN +# define MSAN_CONTAINS_UBSAN CAN_SANITIZE_UB +#endif + struct MappingDesc { uptr start; uptr end; diff --git a/compiler-rt/lib/tsan/CMakeLists.txt b/compiler-rt/lib/tsan/CMakeLists.txt index 68a7bcf3e404..e091f1adf902 100644 --- a/compiler-rt/lib/tsan/CMakeLists.txt +++ b/compiler-rt/lib/tsan/CMakeLists.txt @@ -107,9 +107,11 @@ if(UNIX AND NOT APPLE) $ $ $ + $ CFLAGS ${TSAN_RTL_CFLAGS}) add_compiler_rt_runtime(clang_rt.tsan_cxx-${arch} ${arch} STATIC SOURCES ${TSAN_CXX_SOURCES} + $ CFLAGS ${TSAN_RTL_CFLAGS}) list(APPEND TSAN_RUNTIME_LIBRARIES clang_rt.tsan-${arch} clang_rt.tsan_cxx-${arch}) diff --git a/compiler-rt/lib/tsan/rtl/tsan_defs.h b/compiler-rt/lib/tsan/rtl/tsan_defs.h index 910a483127d5..d869d95e0878 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_defs.h +++ b/compiler-rt/lib/tsan/rtl/tsan_defs.h @@ -17,6 +17,7 @@ #include "sanitizer_common/sanitizer_internal_defs.h" #include "sanitizer_common/sanitizer_libc.h" #include "tsan_stat.h" +#include "ubsan/ubsan_platform.h" // Setup defaults for compile definitions. #ifndef TSAN_NO_HISTORY @@ -27,6 +28,10 @@ # define TSAN_COLLECT_STATS 0 #endif +#ifndef TSAN_CONTAINS_UBSAN +# define TSAN_CONTAINS_UBSAN (CAN_SANITIZE_UB && !defined(SANITIZER_GO)) +#endif + namespace __tsan { #ifdef SANITIZER_GO diff --git a/compiler-rt/lib/tsan/rtl/tsan_flags.cc b/compiler-rt/lib/tsan/rtl/tsan_flags.cc index 4c06600ebc43..5de227a42dee 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_flags.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_flags.cc @@ -17,6 +17,7 @@ #include "tsan_flags.h" #include "tsan_rtl.h" #include "tsan_mman.h" +#include "ubsan/ubsan_flags.h" namespace __tsan { @@ -54,12 +55,6 @@ void RegisterTsanFlags(FlagParser *parser, Flags *f) { } void InitializeFlags(Flags *f, const char *env) { - FlagParser parser; - RegisterTsanFlags(&parser, f); - RegisterCommonFlags(&parser); - - f->SetDefaults(); - SetCommonFlagsDefaults(); { // Override some common flags defaults. @@ -74,10 +69,32 @@ void InitializeFlags(Flags *f, const char *env) { OverrideCommonFlags(cf); } + f->SetDefaults(); + + FlagParser parser; + RegisterTsanFlags(&parser, f); + RegisterCommonFlags(&parser); + +#if TSAN_CONTAINS_UBSAN + __ubsan::Flags *uf = __ubsan::flags(); + uf->SetDefaults(); + + FlagParser ubsan_parser; + __ubsan::RegisterUbsanFlags(&ubsan_parser, uf); + RegisterCommonFlags(&ubsan_parser); +#endif + // Let a frontend override. parser.ParseString(__tsan_default_options()); +#if TSAN_CONTAINS_UBSAN + const char *ubsan_default_options = __ubsan::MaybeCallUbsanDefaultOptions(); + ubsan_parser.ParseString(ubsan_default_options); +#endif // Override from command line. parser.ParseString(env); +#if TSAN_CONTAINS_UBSAN + ubsan_parser.ParseString(GetEnv("UBSAN_OPTIONS")); +#endif // Sanity check. if (!f->report_bugs) { diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.cc b/compiler-rt/lib/tsan/rtl/tsan_rtl.cc index ee279a381957..3eddfcb1b94f 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.cc @@ -24,6 +24,7 @@ #include "tsan_mman.h" #include "tsan_suppressions.h" #include "tsan_symbolize.h" +#include "ubsan/ubsan_init.h" #ifdef __SSE3__ // transitively includes , @@ -350,6 +351,9 @@ void Initialize(ThreadState *thr) { int tid = ThreadCreate(thr, 0, 0, true); CHECK_EQ(tid, 0); ThreadStart(thr, tid, internal_getpid()); +#if TSAN_CONTAINS_UBSAN + __ubsan::InitAsPlugin(); +#endif ctx->initialized = true; if (flags()->stop_on_start) { diff --git a/compiler-rt/test/ubsan/CMakeLists.txt b/compiler-rt/test/ubsan/CMakeLists.txt index 760ce60cc2b8..814ffc2a16a2 100644 --- a/compiler-rt/test/ubsan/CMakeLists.txt +++ b/compiler-rt/test/ubsan/CMakeLists.txt @@ -1,6 +1,20 @@ set(UBSAN_LIT_TESTS_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(UBSAN_TESTSUITES) +set(UBSAN_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS}) + +macro(add_ubsan_testsuite test_mode sanitizer arch) + set(UBSAN_LIT_TEST_MODE "${test_mode}") + set(CONFIG_NAME ${UBSAN_LIT_TEST_MODE}-${arch}) + configure_lit_site_cfg( + ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in + ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg) + list(APPEND UBSAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}) + if(NOT COMPILER_RT_STANDALONE_BUILD) + list(APPEND UBSAN_TEST_DEPS ${sanitizer}) + endif() +endmacro() + foreach(arch ${UBSAN_SUPPORTED_ARCH}) set(UBSAN_TEST_TARGET_ARCH ${arch}) if(${arch} MATCHES "arm|aarch64") @@ -9,28 +23,19 @@ foreach(arch ${UBSAN_SUPPORTED_ARCH}) else() get_target_flags_for_arch(${arch} UBSAN_TEST_TARGET_CFLAGS) endif() - set(UBSAN_LIT_TEST_MODE "Standalone") - set(CONFIG_NAME ${UBSAN_LIT_TEST_MODE}-${arch}) - configure_lit_site_cfg( - ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in - ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg) - list(APPEND UBSAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}) + add_ubsan_testsuite("Standalone" ubsan ${arch}) - if(COMPILER_RT_HAS_ASAN) - set(UBSAN_LIT_TEST_MODE "AddressSanitizer") - set(CONFIG_NAME ${UBSAN_LIT_TEST_MODE}-${arch}) - configure_lit_site_cfg( - ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in - ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg) - list(APPEND UBSAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}) + if(";${ASAN_SUPPORTED_ARCH};" MATCHES ";${arch};") + add_ubsan_testsuite("AddressSanitizer" asan ${arch}) + endif() + if(";${MSAN_SUPPORTED_ARCH};" MATCHES ";${arch};") + add_ubsan_testsuite("MemorySanitizer" msan ${arch}) + endif() + if(";${TSAN_SUPPORTED_ARCH};" MATCHES ";${arch};") + add_ubsan_testsuite("ThreadSanitizer" tsan ${arch}) endif() endforeach() -set(UBSAN_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS}) -if(NOT COMPILER_RT_STANDALONE_BUILD) - list(APPEND UBSAN_TEST_DEPS ubsan asan) -endif() - add_lit_testsuite(check-ubsan "Running UndefinedBehaviorSanitizer tests" ${UBSAN_TESTSUITES} DEPENDS ${UBSAN_TEST_DEPS}) diff --git a/compiler-rt/test/ubsan/TestCases/Misc/Linux/coverage-levels.cc b/compiler-rt/test/ubsan/TestCases/Misc/Linux/coverage-levels.cc index d00b3e03223c..4482a08ef18e 100644 --- a/compiler-rt/test/ubsan/TestCases/Misc/Linux/coverage-levels.cc +++ b/compiler-rt/test/ubsan/TestCases/Misc/Linux/coverage-levels.cc @@ -14,6 +14,9 @@ // RUN: %clangxx -fsanitize=shift -O1 -fsanitize-coverage=3 %s -o %t // RUN: UBSAN_OPTIONS=$OPT %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3 --check-prefix=CHECK_WARN +// Coverage is not yet implemented in TSan. +// XFAIL: ubsan-tsan + volatile int sink; int main(int argc, char **argv) { int shift = argc * 32; diff --git a/compiler-rt/test/ubsan/TestCases/Misc/missing_return.cpp b/compiler-rt/test/ubsan/TestCases/Misc/missing_return.cpp index 5d3d54de17dd..64678f82da40 100644 --- a/compiler-rt/test/ubsan/TestCases/Misc/missing_return.cpp +++ b/compiler-rt/test/ubsan/TestCases/Misc/missing_return.cpp @@ -6,8 +6,8 @@ int f() { // Slow stack unwinding is disabled on Darwin for now, see // https://code.google.com/p/address-sanitizer/issues/detail?id=137 -// CHECK-Linux-STACKTRACE: #0 {{.*}} in f(){{.*}}missing_return.cpp:[[@LINE-3]] -// CHECK-FreeBSD-STACKTRACE: #0 {{.*}} in f(void){{.*}}missing_return.cpp:[[@LINE-4]] +// CHECK-Linux-STACKTRACE: #0 {{.*}}f(){{.*}}missing_return.cpp:[[@LINE-3]] +// CHECK-FreeBSD-STACKTRACE: #0 {{.*}}f(void){{.*}}missing_return.cpp:[[@LINE-4]] // Check for already checked line to avoid lit error reports. // CHECK-Darwin-STACKTRACE: missing_return.cpp } diff --git a/compiler-rt/test/ubsan/TestCases/TypeCheck/misaligned.cpp b/compiler-rt/test/ubsan/TestCases/TypeCheck/misaligned.cpp index 9c8455d5f1c3..0c9275d3f5fc 100644 --- a/compiler-rt/test/ubsan/TestCases/TypeCheck/misaligned.cpp +++ b/compiler-rt/test/ubsan/TestCases/TypeCheck/misaligned.cpp @@ -45,7 +45,7 @@ int main(int, char **argv) { return *p && 0; // Slow stack unwinding is disabled on Darwin for now, see // https://code.google.com/p/address-sanitizer/issues/detail?id=137 - // CHECK-Linux-STACK-LOAD: #0 {{.*}} in main{{.*}}misaligned.cpp + // CHECK-Linux-STACK-LOAD: #0 {{.*}}main{{.*}}misaligned.cpp // Check for the already checked line to avoid lit error reports. // CHECK-Darwin-STACK-LOAD: {{ }} diff --git a/compiler-rt/test/ubsan/TestCases/TypeCheck/vptr.cpp b/compiler-rt/test/ubsan/TestCases/TypeCheck/vptr.cpp index a0681fc04edc..da141c22d11b 100644 --- a/compiler-rt/test/ubsan/TestCases/TypeCheck/vptr.cpp +++ b/compiler-rt/test/ubsan/TestCases/TypeCheck/vptr.cpp @@ -128,7 +128,7 @@ int access_p(T *p, char type) { // CHECK-MEMBER-NEXT: {{^ .. .. .. .. .. .. .. .. .. .. .. .. }} // CHECK-MEMBER-NEXT: {{^ \^~~~~~~~~~~(~~~~~~~~~~~~)? *$}} // CHECK-MEMBER-NEXT: {{^ vptr for}} [[DYN_TYPE]] - // CHECK-MEMBER-NEXT: #0 {{.*}} in access_p{{.*}}vptr.cpp:[[@LINE+1]] + // CHECK-MEMBER-NEXT: #0 {{.*}}access_p{{.*}}vptr.cpp:[[@LINE+1]] return p->b; // CHECK-NULL-MEMBER: vptr.cpp:[[@LINE-2]]:15: runtime error: member access within address [[PTR:0x[0-9a-f]*]] which does not point to an object of type 'T' @@ -136,7 +136,7 @@ int access_p(T *p, char type) { // CHECK-NULL-MEMBER-NEXT: {{^ ?.. .. .. .. ?00 00 00 00 ?00 00 00 00 ?}} // CHECK-NULL-MEMBER-NEXT: {{^ \^~~~~~~~~~~(~~~~~~~~~~~~)? *$}} // CHECK-NULL-MEMBER-NEXT: {{^ invalid vptr}} - // CHECK-NULL-MEMBER-NEXT: #0 {{.*}} in access_p{{.*}}vptr.cpp:[[@LINE-7]] + // CHECK-NULL-MEMBER-NEXT: #0 {{.*}}access_p{{.*}}vptr.cpp:[[@LINE-7]] case 'f': // CHECK-MEMFUN: vptr.cpp:[[@LINE+6]]:12: runtime error: member call on address [[PTR:0x[0-9a-f]*]] which does not point to an object of type 'T' @@ -153,7 +153,7 @@ int access_p(T *p, char type) { // CHECK-OFFSET-NEXT: {{^ .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. }} // CHECK-OFFSET-NEXT: {{^ \^ ( ~~~~~~~~~~~~)?~~~~~~~~~~~ *$}} // CHECK-OFFSET-NEXT: {{^ ( )?vptr for}} 'T' base class of [[DYN_TYPE]] - // CHECK-OFFSET-NEXT: #0 {{.*}} in access_p{{.*}}vptr.cpp:[[@LINE+1]] + // CHECK-OFFSET-NEXT: #0 {{.*}}access_p{{.*}}vptr.cpp:[[@LINE+1]] return reinterpret_cast(p)->v() - 2; case 'c': @@ -162,7 +162,7 @@ int access_p(T *p, char type) { // CHECK-DOWNCAST-NEXT: {{^ .. .. .. .. .. .. .. .. .. .. .. .. }} // CHECK-DOWNCAST-NEXT: {{^ \^~~~~~~~~~~(~~~~~~~~~~~~)? *$}} // CHECK-DOWNCAST-NEXT: {{^ vptr for}} [[DYN_TYPE]] - // CHECK-DOWNCAST-NEXT: #0 {{.*}} in access_p{{.*}}vptr.cpp:[[@LINE+1]] + // CHECK-DOWNCAST-NEXT: #0 {{.*}}access_p{{.*}}vptr.cpp:[[@LINE+1]] static_cast(reinterpret_cast(p)); return 0; } diff --git a/compiler-rt/test/ubsan/lit.common.cfg b/compiler-rt/test/ubsan/lit.common.cfg index 630172954603..5d3e78eec76b 100644 --- a/compiler-rt/test/ubsan/lit.common.cfg +++ b/compiler-rt/test/ubsan/lit.common.cfg @@ -25,6 +25,14 @@ elif ubsan_lit_test_mode == "AddressSanitizer": config.available_features.add("ubsan-asan") clang_ubsan_cflags = ["-fsanitize=address"] config.environment['ASAN_OPTIONS'] = 'detect_leaks=0' +elif ubsan_lit_test_mode == "MemorySanitizer": + config.name = 'UBSan-MSan-' + config.target_arch + config.available_features.add("ubsan-msan") + clang_ubsan_cflags = ["-fsanitize=memory"] +elif ubsan_lit_test_mode == "ThreadSanitizer": + config.name = 'UBSan-TSan-' + config.target_arch + config.available_features.add("ubsan-tsan") + clang_ubsan_cflags = ["-fsanitize=thread"] else: lit_config.fatal("Unknown UBSan test mode: %r" % ubsan_lit_test_mode)