diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake --- a/compiler-rt/cmake/config-ix.cmake +++ b/compiler-rt/cmake/config-ix.cmake @@ -672,6 +672,12 @@ set(COMPILER_RT_HAS_TSAN FALSE) endif() +if (OS_NAME MATCHES "Linux|FreeBSD|Windows|NetBSD|SunOS") + set(COMPILER_RT_TSAN_HAS_STATIC_RUNTIME TRUE) +else() + set(COMPILER_RT_TSAN_HAS_STATIC_RUNTIME FALSE) +endif() + if (COMPILER_RT_HAS_SANITIZER_COMMON AND UBSAN_SUPPORTED_ARCH AND OS_NAME MATCHES "Darwin|Linux|FreeBSD|NetBSD|Windows|Android|Fuchsia|SunOS") set(COMPILER_RT_HAS_UBSAN TRUE) diff --git a/compiler-rt/lib/tsan/CMakeLists.txt b/compiler-rt/lib/tsan/CMakeLists.txt --- a/compiler-rt/lib/tsan/CMakeLists.txt +++ b/compiler-rt/lib/tsan/CMakeLists.txt @@ -24,6 +24,12 @@ append_list_if(COMPILER_RT_HAS_WGLOBAL_CONSTRUCTORS_FLAG -Wglobal-constructors TSAN_RTL_CFLAGS) +set(TSAN_RTL_DYNAMIC_CFLAGS ${TSAN_RTL_CFLAGS}) +list(REMOVE_ITEM TSAN_RTL_DYNAMIC_CFLAGS -fPIE) + +append_list_if(COMPILER_RT_HAS_LIBDL dl TSAN_DYNAMIC_LINK_LIBS) +append_list_if(COMPILER_RT_HAS_LIBPTHREAD pthread TSAN_DYNAMIC_LINK_LIBS) + set(TSAN_SOURCES rtl/tsan_clock.cpp rtl/tsan_debugging.cpp @@ -257,6 +263,20 @@ PARENT_TARGET tsan) list(APPEND TSAN_RUNTIME_LIBRARIES clang_rt.tsan-${arch} clang_rt.tsan_cxx-${arch}) + add_compiler_rt_runtime(clang_rt.tsan + SHARED + ARCHS ${arch} + SOURCES ${TSAN_SOURCES} ${TSAN_ASM_SOURCES} + $ + $ + $ + $ + $ + $ + ADDITIONAL_HEADERS ${TSAN_HEADERS} + CFLAGS ${TSAN_RTL_DYNAMIC_CFLAGS} + LINK_LIBS ${TSAN_DYNAMIC_LINK_LIBS} + PARENT_TARGET tsan) add_sanitizer_rt_symbols(clang_rt.tsan ARCHS ${arch} EXTRA rtl/tsan.syms.extra) diff --git a/compiler-rt/lib/tsan/tests/CMakeLists.txt b/compiler-rt/lib/tsan/tests/CMakeLists.txt --- a/compiler-rt/lib/tsan/tests/CMakeLists.txt +++ b/compiler-rt/lib/tsan/tests/CMakeLists.txt @@ -4,6 +4,11 @@ set_target_properties(TsanUnitTests PROPERTIES FOLDER "Compiler-RT Tests") +# ThreadSanitizer unit tests with dynamic runtime (on platforms where it's +# not the default). +add_custom_target(TsanDynamicUnitTests) +set_target_properties(TsanDynamicUnitTests PROPERTIES FOLDER "Compiler-RT Tests") + set(TSAN_UNITTEST_CFLAGS ${COMPILER_RT_UNITTEST_CFLAGS} ${COMPILER_RT_GTEST_CFLAGS} @@ -55,6 +60,55 @@ list(APPEND LINK_FLAGS ${COMPILER_RT_TEST_LIBDISPATCH_CFLAGS}) endif() +function(add_tsan_tests arch test_runtime) + cmake_parse_arguments(TEST "" "KIND" "CFLAGS" ${ARGN}) + + # Closure to keep the values. + function(generate_tsan_tests test_objects test_suite testname) + generate_compiler_rt_tests(${test_objects} ${test_suite} ${testname} ${arch} + COMPILE_DEPS ${ASAN_UNITTEST_HEADERS} ${ASAN_IGNORELIST_FILE} + DEPS gtest tsan + KIND ${TEST_KIND} + ${ARGN} + ) + set("${test_objects}" "${${test_objects}}" PARENT_SCOPE) + endfunction() + set(TSAN_INST_TEST_OBJECTS) + generate_tsan_tests(TSAN_INST_TEST_OBJECTS TsanUnitTests + "Asan-${arch}${TEST_KIND}-Test" + SUBDIR "default" + LINK_FLAGS ${TSAN_UNITTEST_INSTRUMENTED_LINK_FLAGS} + SOURCES ${TSAN_INST_TEST_SOURCES} + CFLAGS ${TSAN_UNITTEST_INSTRUMENTED_CFLAGS} ${TEST_CFLAGS}) + + if(COMPILER_RT_TSAN_HAS_STATIC_RUNTIME) + set(dynamic_test_name "Tsan-${arch}${TEST_KIND}-Dynamic-Test") + if(MSVC) + + # With the MSVC CRT, the choice between static and dynamic CRT is made at + # compile time with a macro. Simulate the effect of passing /MD to clang-cl. + set(TSAN_DYNAMIC_TEST_OBJECTS) + generate_tsan_tests(TSAN_DYNAMIC_TEST_OBJECTS + TsanDynamicUnitTests "${dynamic_test_name}" + SUBDIR "dynamic" + CFLAGS ${TSAN_UNITTEST_INSTRUMENTED_CFLAGS} -D_MT -D_DLL + SOURCES ${TSAN_INST_TEST_SOURCES} + LINK_FLAGS ${TSAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINK_FLAGS} + -Wl,-nodefaultlib:libcmt,-defaultlib:msvcrt,-defaultlib:oldnames + ) + else() + + # Otherwise, reuse TSAN_INST_TEST_OBJECTS. + add_compiler_rt_test(TsanDynamicUnitTests "${dynamic_test_name}" "${arch}" + SUBDIR "dynamic" + OBJECTS ${TSAN_INST_TEST_OBJECTS} + DEPS tsan ${TSAN_INST_TEST_OBJECTS} + LINK_FLAGS ${TSAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINK_FLAGS} + ) + endif() + endif() +endfunction() + set(TSAN_RTL_HEADERS) foreach (header ${TSAN_HEADERS}) list(APPEND TSAN_RTL_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../${header}) diff --git a/compiler-rt/test/tsan/CMakeLists.txt b/compiler-rt/test/tsan/CMakeLists.txt --- a/compiler-rt/test/tsan/CMakeLists.txt +++ b/compiler-rt/test/tsan/CMakeLists.txt @@ -42,12 +42,26 @@ string(TOUPPER ${arch} ARCH_UPPER_CASE) set(CONFIG_NAME ${ARCH_UPPER_CASE}Config) - configure_lit_site_cfg( + if(COMPILER_RT_TSAN_HAS_STATIC_RUNTIME) + string(TOLOWER "-${arch}-${OS_NAME}-dynamic" TSAN_TEST_CONFIG_SUFFIX) + set(TSAN_TEST_DYNAMIC True) + set(CONFIG_NAME ${ARCH_UPPER_CASE}${OS_NAME}DynamicConfig) + configure_lit_site_cfg( + ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in + ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg.py + MAIN_CONFIG + ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py + ) + list(APPEND TSAN_DYNAMIC_TESTSUITES + ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}) + else() + configure_lit_site_cfg( ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg.py MAIN_CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py ) + endif() list(APPEND TSAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}) endforeach() @@ -98,11 +112,28 @@ configure_lit_site_cfg( ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.py.in ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg.py) + if(COMPILER_RT_TSAN_HAS_STATIC_RUNTIME) + set(TSAN_TEST_DYNAMIC True) + configure_lit_site_cfg( + ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.py.in + ${CMAKE_CURRENT_BINARY_DIR}/Unit/dynamic/lit.site.cfg.py) + endif() list(APPEND TSAN_TEST_DEPS TsanUnitTests) list(APPEND TSAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/Unit) + if(COMPILER_RT_TSAN_HAS_STATIC_RUNTIME) + list(APPEND TSAN_DYNAMIC_TEST_DEPS TsanDynamicUnitTests) + list(APPEND TSAN_DYNAMIC_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/Unit/dynamic) + endif() endif() add_lit_testsuite(check-tsan "Running ThreadSanitizer tests" ${TSAN_TESTSUITES} DEPENDS ${TSAN_TEST_DEPS}) set_target_properties(check-tsan PROPERTIES FOLDER "Compiler-RT Tests") + +if(COMPILER_RT_TSAN_HAS_STATIC_RUNTIME) + add_lit_testsuite(check-tsan-dynamic "Running the ThreadSanitizer tests with dynamic runtime" + ${TSAN_DYNAMIC_TESTSUITES} + DEPENDS ${TSAN_DYNAMIC_TEST_DEPS}) + set_target_properties(check-tsan-dynamic PROPERTIES FOLDER "Compiler-RT Misc") +endif() diff --git a/compiler-rt/test/tsan/lit.site.cfg.py.in b/compiler-rt/test/tsan/lit.site.cfg.py.in --- a/compiler-rt/test/tsan/lit.site.cfg.py.in +++ b/compiler-rt/test/tsan/lit.site.cfg.py.in @@ -7,6 +7,7 @@ config.apple_platform_min_deployment_target_flag = "@TSAN_TEST_MIN_DEPLOYMENT_TARGET_FLAG@" config.target_cflags = "@TSAN_TEST_TARGET_CFLAGS@" config.target_arch = "@TSAN_TEST_TARGET_ARCH@" +config.tsan_dynamic = @TSAN_TEST_DYNAMIC@ config.deflake_threshold = "@TSAN_TEST_DEFLAKE_THRESHOLD@" # Load common config for all compiler-rt lit tests.