Skip to content

Commit ed88919

Browse files
tchaikovavikivity
authored andcommitted
build: check the combination of Sanitizers
we are going to add a build with ThreadSanitizer enabled, but ThreadSanitizer cannot be used along with AddressSanitizer. the existing sanitizer detection checks each sanitizer separately, so even if the sanitizers combination does not work, the detection still passes. also, we hardwire two sanitizers in `FindSanitizers.cmake`, this is not extensible to the use case where we only need to selectively find a certain (combination) of sanitizers. in order to address these problems, in this change * find specified component(s) in FindSanitizers.cmake, to prepare for the change which selectively specifies a subset of sanitizers * check if the compiler supports the combination of compile options required by all specified sanitizers Signed-off-by: Kefu Chai <[email protected]>
1 parent 5e9b43a commit ed88919

File tree

1 file changed

+48
-39
lines changed

1 file changed

+48
-39
lines changed

cmake/FindSanitizers.cmake

+48-39
Original file line numberDiff line numberDiff line change
@@ -20,54 +20,63 @@
2020
# Copyright (C) 2018 Scylladb, Ltd.
2121
#
2222

23-
include (CheckCXXSourceCompiles)
23+
if(NOT Sanitizers_FIND_COMPONENTS)
24+
set(Sanitizers_FIND_COMPONENTS
25+
address
26+
undefined_behavior)
27+
endif()
2428

25-
set (CMAKE_REQUIRED_FLAGS -fsanitize=address)
26-
check_cxx_source_compiles ("int main() {}" Sanitizers_ADDRESS_FOUND)
27-
28-
if (Sanitizers_ADDRESS_FOUND)
29-
set (Sanitizers_ADDRESS_COMPILER_OPTIONS -fsanitize=address)
30-
endif ()
29+
foreach (component ${Sanitizers_FIND_COMPONENTS})
30+
string (TOUPPER ${component} COMPONENT)
31+
set (compile_options "Sanitizers_${COMPONENT}_COMPILE_OPTIONS")
32+
if (component STREQUAL "address")
33+
list (APPEND ${compile_options} -fsanitize=address)
34+
elseif (component STREQUAL "undefined_behavior")
35+
list (APPEND ${compile_options} -fsanitize=undefined)
36+
# Disable vptr because of https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88684
37+
list (APPEND ${compile_options} -fno-sanitize=vptr)
38+
else ()
39+
message (FATAL_ERROR "Unsupported sanitizer: ${component}")
40+
endif ()
41+
list(APPEND Sanitizers_COMPILE_OPTIONS "${${compile_options}}")
42+
endforeach ()
3143

32-
set (CMAKE_REQUIRED_FLAGS -fsanitize=undefined)
33-
check_cxx_source_compiles ("int main() {}" Sanitizers_UNDEFINED_BEHAVIOR_FOUND)
44+
include(CheckCXXSourceCompiles)
45+
include(CMakePushCheckState)
3446

35-
if (Sanitizers_UNDEFINED_BEHAVIOR_FOUND)
36-
# Disable vptr because of https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88684
37-
set (Sanitizers_UNDEFINED_BEHAVIOR_COMPILER_OPTIONS "-fsanitize=undefined;-fno-sanitize=vptr")
47+
# -fsanitize=address cannot be combined with -fsanitize=thread, so let's test
48+
# the combination of the compiler options.
49+
cmake_push_check_state()
50+
string (REPLACE ";" " " CMAKE_REQUIRED_FLAGS "${Sanitizers_COMPILE_OPTIONS}")
51+
set(CMAKE_REQUIRED_FLAGS ${Sanitizers_COMPILE_OPTIONS})
52+
check_cxx_source_compiles("int main() {}"
53+
Sanitizers_SUPPORTED)
54+
if (Sanitizers_SUPPORTED)
55+
if ("address" IN_LIST Sanitizers_FIND_COMPONENTS)
56+
file (READ ${CMAKE_CURRENT_LIST_DIR}/code_tests/Sanitizers_fiber_test.cc _sanitizers_fiber_test_code)
57+
check_cxx_source_compiles ("${_sanitizers_fiber_test_code}"
58+
Sanitizers_FIBER_SUPPORT)
59+
endif ()
3860
endif ()
39-
40-
set (Sanitizers_COMPILER_OPTIONS
41-
${Sanitizers_ADDRESS_COMPILER_OPTIONS}
42-
${Sanitizers_UNDEFINED_BEHAVIOR_COMPILER_OPTIONS})
43-
44-
file (READ ${CMAKE_CURRENT_LIST_DIR}/code_tests/Sanitizers_fiber_test.cc _sanitizers_fiber_test_code)
45-
set (CMAKE_REQUIRED_FLAGS ${Sanitizers_COMPILER_OPTIONS})
46-
check_cxx_source_compiles ("${_sanitizers_fiber_test_code}" Sanitizers_FIBER_SUPPORT)
61+
cmake_pop_check_state()
4762

4863
include (FindPackageHandleStandardArgs)
4964

5065
find_package_handle_standard_args (Sanitizers
5166
REQUIRED_VARS
52-
Sanitizers_ADDRESS_COMPILER_OPTIONS
53-
Sanitizers_UNDEFINED_BEHAVIOR_COMPILER_OPTIONS)
67+
Sanitizers_COMPILE_OPTIONS
68+
Sanitizers_SUPPORTED)
5469

5570
if (Sanitizers_FOUND)
56-
if (NOT (TARGET Sanitizers::address))
57-
add_library (Sanitizers::address INTERFACE IMPORTED)
58-
59-
set_target_properties (Sanitizers::address
60-
PROPERTIES
61-
INTERFACE_COMPILE_OPTIONS ${Sanitizers_ADDRESS_COMPILER_OPTIONS}
62-
INTERFACE_LINK_LIBRARIES ${Sanitizers_ADDRESS_COMPILER_OPTIONS})
63-
endif ()
64-
65-
if (NOT (TARGET Sanitizers::undefined_behavior))
66-
add_library (Sanitizers::undefined_behavior INTERFACE IMPORTED)
67-
68-
set_target_properties (Sanitizers::undefined_behavior
69-
PROPERTIES
70-
INTERFACE_COMPILE_OPTIONS "${Sanitizers_UNDEFINED_BEHAVIOR_COMPILER_OPTIONS}"
71-
INTERFACE_LINK_LIBRARIES "${Sanitizers_UNDEFINED_BEHAVIOR_COMPILER_OPTIONS}")
72-
endif ()
71+
foreach (component ${Sanitizers_FIND_COMPONENTS})
72+
string (TOUPPER ${component} COMPONENT)
73+
set (library Sanitizers::${component})
74+
if (NOT TARGET ${library})
75+
add_library (${library} INTERFACE IMPORTED)
76+
set_target_properties (${library}
77+
PROPERTIES
78+
INTERFACE_COMPILE_OPTIONS "${Sanitizers_${COMPONENT}_COMPILE_OPTIONS}"
79+
INTERFACE_LINK_LIBRARIES "${Sanitizers_${COMPONENT}_COMPILE_OPTIONS}")
80+
endif ()
81+
endforeach ()
7382
endif ()

0 commit comments

Comments
 (0)