Index: cmake/Modules/CompilerRTUtils.cmake =================================================================== --- cmake/Modules/CompilerRTUtils.cmake +++ cmake/Modules/CompilerRTUtils.cmake @@ -36,6 +36,16 @@ endif() endmacro() +# Appends values to list if it isn't already there +macro(append_list_unique list) + foreach(val ${ARGN}) + list(FIND ${list} ${val} idx) + if(idx EQUAL -1) + list(APPEND ${list} ${val}) + endif() + endforeach() +endmacro() + # Appends value to all strings in ARGN, if the condition is true. macro(append_string_if condition value) if(${condition}) @@ -67,3 +77,18 @@ endif() endforeach() endmacro() + +macro(is_in_list outvar list input) + list(FIND ${list} ${input} idx) + if(idx GREATER -1) + set(${outvar} On) + else() + set(${outvar} Off) + endif() +endmacro() + +macro(is_runtime_building outvar runtime) + is_in_list(${outvar} COMPILER_RT_RUNTIMES_TO_BUILD ${runtime}) +endmacro() + + Index: cmake/config-ix.cmake =================================================================== --- cmake/config-ix.cmake +++ cmake/config-ix.cmake @@ -504,73 +504,62 @@ if (SANITIZER_COMMON_SUPPORTED_ARCH AND NOT LLVM_USE_SANITIZER AND (OS_NAME MATCHES "Android|Darwin|Linux|FreeBSD" OR (OS_NAME MATCHES "Windows" AND MSVC))) - set(COMPILER_RT_HAS_SANITIZER_COMMON TRUE) -else() - set(COMPILER_RT_HAS_SANITIZER_COMMON FALSE) + list(APPEND DEFAULT_RUNTIMES sanitizer_common) endif() -if (COMPILER_RT_HAS_SANITIZER_COMMON AND - (NOT OS_NAME MATCHES "Windows" OR CMAKE_SIZEOF_VOID_P EQUAL 4)) - set(COMPILER_RT_HAS_INTERCEPTION TRUE) -else() - set(COMPILER_RT_HAS_INTERCEPTION FALSE) +if (NOT OS_NAME MATCHES "Windows" OR CMAKE_SIZEOF_VOID_P EQUAL 4) + list(APPEND DEFAULT_RUNTIMES interception) + list(APPEND REQUIRES_COMMON interception) endif() -if (COMPILER_RT_HAS_SANITIZER_COMMON AND ASAN_SUPPORTED_ARCH AND +if (ASAN_SUPPORTED_ARCH AND (NOT OS_NAME MATCHES "Windows" OR CMAKE_SIZEOF_VOID_P EQUAL 4)) - set(COMPILER_RT_HAS_ASAN TRUE) -else() - set(COMPILER_RT_HAS_ASAN FALSE) + list(APPEND DEFAULT_RUNTIMES asan) + list(APPEND REQUIRES_COMMON asan) endif() if (OS_NAME MATCHES "Linux|FreeBSD|Windows") - set(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME TRUE) -else() - set(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME FALSE) + set(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME On) endif() # TODO: Add builtins support. -if (COMPILER_RT_HAS_SANITIZER_COMMON AND DFSAN_SUPPORTED_ARCH AND +if (DFSAN_SUPPORTED_ARCH AND OS_NAME MATCHES "Linux") - set(COMPILER_RT_HAS_DFSAN TRUE) -else() - set(COMPILER_RT_HAS_DFSAN FALSE) + list(APPEND DEFAULT_RUNTIMES dfsan) + list(APPEND REQUIRES_COMMON dfsan) endif() -if (COMPILER_RT_HAS_SANITIZER_COMMON AND LSAN_SUPPORTED_ARCH AND - OS_NAME MATCHES "Linux|FreeBSD") - set(COMPILER_RT_HAS_LSAN TRUE) -else() - set(COMPILER_RT_HAS_LSAN FALSE) +if (LSAN_SUPPORTED_ARCH AND OS_NAME MATCHES "Linux|FreeBSD") + list(APPEND DEFAULT_RUNTIMES lsan) + list(APPEND REQUIRES_COMMON lsan) endif() -if (COMPILER_RT_HAS_SANITIZER_COMMON AND MSAN_SUPPORTED_ARCH AND +if (MSAN_SUPPORTED_ARCH AND OS_NAME MATCHES "Linux") - set(COMPILER_RT_HAS_MSAN TRUE) -else() - set(COMPILER_RT_HAS_MSAN FALSE) + list(APPEND DEFAULT_RUNTIMES msan) + list(APPEND REQUIRES_COMMON msan) endif() if (PROFILE_SUPPORTED_ARCH AND OS_NAME MATCHES "Darwin|Linux|FreeBSD") - set(COMPILER_RT_HAS_PROFILE TRUE) -else() - set(COMPILER_RT_HAS_PROFILE FALSE) + list(APPEND DEFAULT_RUNTIMES profile) endif() -if (COMPILER_RT_HAS_SANITIZER_COMMON AND TSAN_SUPPORTED_ARCH AND +if (TSAN_SUPPORTED_ARCH AND OS_NAME MATCHES "Darwin|Linux|FreeBSD") - set(COMPILER_RT_HAS_TSAN TRUE) -else() - set(COMPILER_RT_HAS_TSAN FALSE) + list(APPEND DEFAULT_RUNTIMES tsan) + list(APPEND REQUIRES_COMMON tsan) endif() -if (COMPILER_RT_HAS_SANITIZER_COMMON AND UBSAN_SUPPORTED_ARCH AND +if (UBSAN_SUPPORTED_ARCH AND OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows") - set(COMPILER_RT_HAS_UBSAN TRUE) -else() - set(COMPILER_RT_HAS_UBSAN FALSE) + list(APPEND DEFAULT_RUNTIMES ubsan) + list(APPEND REQUIRES_COMMON ubsan) +endif() + +if(OS_NAME MATCHES "Windows") + list(APPEND DEFAULT_RUNTIMES cfi) endif() # -msse3 flag is not valid for Mips therefore clang gives a warning @@ -581,9 +570,25 @@ set(COMPILER_RT_HAS_MSSE3_FLAG FALSE) endif() -if (COMPILER_RT_HAS_SANITIZER_COMMON AND SAFESTACK_SUPPORTED_ARCH AND +if (SAFESTACK_SUPPORTED_ARCH AND OS_NAME MATCHES "Darwin|Linux|FreeBSD") - set(COMPILER_RT_HAS_SAFESTACK TRUE) -else() - set(COMPILER_RT_HAS_SAFESTACK FALSE) + list(APPEND DEFAULT_RUNTIMES safestack) + list(APPEND REQUIRES_COMMON safestack) +endif() + +set(COMPILER_RT_RUNTIMES_TO_BUILD "all" + CACHE STRING "Semicolon-separated list of runtimes to build, or \"all\".") + +if(COMPILER_RT_RUNTIMES_TO_BUILD STREQUAL "all") + set(COMPILER_RT_RUNTIMES_TO_BUILD ${DEFAULT_RUNTIMES}) endif() + +list_union(SHOULD_BUILD_COMMON REQUIRES_COMMON COMPILER_RT_RUNTIMES_TO_BUILD) + +if(SHOULD_BUILD_COMMON) + append_list_unique(COMPILER_RT_RUNTIMES_TO_BUILD sanitizer_common) + append_list_unique(COMPILER_RT_RUNTIMES_TO_BUILD lsan) + append_list_unique(COMPILER_RT_RUNTIMES_TO_BUILD ubsan) + append_list_unique(COMPILER_RT_RUNTIMES_TO_BUILD interception) +endif() + Index: lib/CMakeLists.txt =================================================================== --- lib/CMakeLists.txt +++ lib/CMakeLists.txt @@ -9,40 +9,9 @@ endif() if(COMPILER_RT_BUILD_SANITIZERS) - if(COMPILER_RT_HAS_INTERCEPTION) - add_subdirectory(interception) - endif() - - if(COMPILER_RT_HAS_SANITIZER_COMMON) - add_subdirectory(sanitizer_common) - add_subdirectory(lsan) - add_subdirectory(ubsan) - endif() - - add_subdirectory(cfi) - - if(COMPILER_RT_HAS_ASAN) - add_subdirectory(asan) - endif() - - if(COMPILER_RT_HAS_DFSAN) - add_subdirectory(dfsan) - endif() - - if(COMPILER_RT_HAS_MSAN) - add_subdirectory(msan) - endif() - - if(COMPILER_RT_HAS_PROFILE) - add_subdirectory(profile) - endif() - - if(COMPILER_RT_HAS_TSAN) - add_subdirectory(tsan) - add_subdirectory(tsan/dd) - endif() - - if(COMPILER_RT_HAS_SAFESTACK) - add_subdirectory(safestack) - endif() + message(STATUS "Adding runtimes...") + foreach(runtime ${COMPILER_RT_RUNTIMES_TO_BUILD}) + message(STATUS "Adding runtime: ${runtime}") + add_subdirectory(${runtime}) + endforeach() endif() Index: lib/lsan/CMakeLists.txt =================================================================== --- lib/lsan/CMakeLists.txt +++ lib/lsan/CMakeLists.txt @@ -24,7 +24,8 @@ SOURCES ${LSAN_COMMON_SOURCES} CFLAGS ${LSAN_CFLAGS}) -if(COMPILER_RT_HAS_LSAN) +is_runtime_building(BUILDING_LSAN lsan) +if(BUILDING_LSAN) foreach(arch ${LSAN_SUPPORTED_ARCH}) add_compiler_rt_runtime(clang_rt.lsan STATIC Index: lib/tsan/CMakeLists.txt =================================================================== --- lib/tsan/CMakeLists.txt +++ lib/tsan/CMakeLists.txt @@ -192,3 +192,5 @@ if(COMPILER_RT_INCLUDE_TESTS) add_subdirectory(tests) endif() + +add_subdirectory(dd) Index: lib/ubsan/CMakeLists.txt =================================================================== --- lib/ubsan/CMakeLists.txt +++ lib/ubsan/CMakeLists.txt @@ -1,5 +1,7 @@ # Build for the undefined behavior sanitizer runtime support library. +is_runtime_building(COMPILER_RT_HAS_UBSAN ubsan) + set(UBSAN_SOURCES ubsan_diag.cc ubsan_init.cc Index: test/CMakeLists.txt =================================================================== --- test/CMakeLists.txt +++ test/CMakeLists.txt @@ -36,37 +36,9 @@ # Run sanitizer tests only if we're sure that clang would produce # working binaries. if(COMPILER_RT_CAN_EXECUTE_TESTS) - if(COMPILER_RT_HAS_ASAN) - add_subdirectory(asan) - endif() - if(COMPILER_RT_HAS_DFSAN) - add_subdirectory(dfsan) - endif() - if(COMPILER_RT_HAS_LSAN) - add_subdirectory(lsan) - endif() - if(COMPILER_RT_HAS_MSAN) - add_subdirectory(msan) - endif() - if(COMPILER_RT_HAS_PROFILE) - add_subdirectory(profile) - endif() - if(COMPILER_RT_HAS_SANITIZER_COMMON) - add_subdirectory(sanitizer_common) - endif() - if(COMPILER_RT_HAS_TSAN) - add_subdirectory(tsan) - endif() - if(COMPILER_RT_HAS_UBSAN) - add_subdirectory(ubsan) - endif() - # CFI tests require diagnostic mode, which is implemented in UBSan. - if(COMPILER_RT_HAS_UBSAN) - add_subdirectory(cfi) - endif() - if(COMPILER_RT_HAS_SAFESTACK) - add_subdirectory(safestack) - endif() + foreach(runtime ${COMPILER_RT_RUNTIMES_TO_BUILD}) + add_subdirectory(${runtime}) + endforeach() endif() if(COMPILER_RT_STANDALONE_BUILD) @@ -79,3 +51,4 @@ ${LLVM_LIT_TESTSUITES} DEPENDS ${LLVM_LIT_DEPENDS}) endif() + Index: test/interception/CMakeLists.txt =================================================================== --- /dev/null +++ test/interception/CMakeLists.txt @@ -0,0 +1 @@ +# Placeholder to avoid special casing. Index: test/ubsan/CMakeLists.txt =================================================================== --- test/ubsan/CMakeLists.txt +++ test/ubsan/CMakeLists.txt @@ -20,6 +20,10 @@ darwin_filter_host_archs(UBSAN_SUPPORTED_ARCH UBSAN_TEST_ARCH) endif() +is_runtime_building(HAS_ASAN asan) +is_runtime_building(HAS_MSAN msan) +is_runtime_building(HAS_TSAN tsan) + foreach(arch ${UBSAN_TEST_ARCH}) set(UBSAN_TEST_TARGET_ARCH ${arch}) if(${arch} MATCHES "arm|aarch64") @@ -31,13 +35,17 @@ endif() add_ubsan_testsuite("Standalone" ubsan ${arch}) - if(COMPILER_RT_HAS_ASAN AND ";${ASAN_SUPPORTED_ARCH};" MATCHES ";${arch};") + is_in_list(ASAN_HAS_ARCH ASAN_SUPPORTED_ARCH ${arch}) + is_in_list(MSAN_HAS_ARCH MSAN_SUPPORTED_ARCH ${arch}) + is_in_list(TSAN_HAS_ARCH TSAN_SUPPORTED_ARCH ${arch}) + + if(HAS_ASAN AND ASAN_HAS_ARCH) add_ubsan_testsuite("AddressSanitizer" asan ${arch}) endif() - if(COMPILER_RT_HAS_MSAN AND ";${MSAN_SUPPORTED_ARCH};" MATCHES ";${arch};") + if(HAS_MSAN AND MSAN_HAS_ARCH) add_ubsan_testsuite("MemorySanitizer" msan ${arch}) endif() - if(COMPILER_RT_HAS_TSAN AND ";${TSAN_SUPPORTED_ARCH};" MATCHES ";${arch};") + if(HAS_TSAN AND TSAN_HAS_ARCH) add_ubsan_testsuite("ThreadSanitizer" tsan ${arch}) endif() endforeach()