mirror of https://github.com/opencv/opencv.git
Open Source Computer Vision Library
https://opencv.org/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
166 lines
5.6 KiB
166 lines
5.6 KiB
# detect-sanitizer.cmake -- Detect supported compiler sanitizer flags |
|
# Licensed under the Zlib license, see LICENSE.md for details |
|
|
|
macro(add_common_sanitizer_flags) |
|
if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") |
|
add_compile_options(-g3) |
|
endif() |
|
check_c_compiler_flag(-fno-omit-frame-pointer HAVE_NO_OMIT_FRAME_POINTER) |
|
if(HAVE_NO_OMIT_FRAME_POINTER) |
|
add_compile_options(-fno-omit-frame-pointer) |
|
add_link_options(-fno-omit-frame-pointer) |
|
endif() |
|
check_c_compiler_flag(-fno-optimize-sibling-calls HAVE_NO_OPTIMIZE_SIBLING_CALLS) |
|
if(HAVE_NO_OPTIMIZE_SIBLING_CALLS) |
|
add_compile_options(-fno-optimize-sibling-calls) |
|
add_link_options(-fno-optimize-sibling-calls) |
|
endif() |
|
endmacro() |
|
|
|
macro(check_sanitizer_support known_checks supported_checks) |
|
set(available_checks "") |
|
|
|
# Build list of supported sanitizer flags by incrementally trying compilation with |
|
# known sanitizer checks |
|
|
|
foreach(check ${known_checks}) |
|
if(available_checks STREQUAL "") |
|
set(compile_checks "${check}") |
|
else() |
|
set(compile_checks "${available_checks},${check}") |
|
endif() |
|
|
|
set(CMAKE_REQUIRED_FLAGS -fsanitize=${compile_checks}) |
|
|
|
check_c_source_compiles("int main() { return 0; }" HAVE_SANITIZER_${check} |
|
FAIL_REGEX "not supported|unrecognized command|unknown option") |
|
|
|
set(CMAKE_REQUIRED_FLAGS) |
|
|
|
if(HAVE_SANITIZER_${check}) |
|
set(available_checks ${compile_checks}) |
|
endif() |
|
endforeach() |
|
|
|
set(${supported_checks} ${available_checks}) |
|
endmacro() |
|
|
|
macro(add_address_sanitizer) |
|
set(known_checks |
|
address |
|
pointer-compare |
|
pointer-subtract |
|
) |
|
|
|
check_sanitizer_support("${known_checks}" supported_checks) |
|
if(NOT ${supported_checks} STREQUAL "") |
|
message(STATUS "Address sanitizer is enabled: ${supported_checks}") |
|
add_compile_options(-fsanitize=${supported_checks}) |
|
add_link_options(-fsanitize=${supported_checks}) |
|
add_common_sanitizer_flags() |
|
else() |
|
message(STATUS "Address sanitizer is not supported") |
|
endif() |
|
|
|
if(CMAKE_CROSSCOMPILING_EMULATOR) |
|
# Only check for leak sanitizer if not cross-compiling due to qemu crash |
|
message(WARNING "Leak sanitizer is not supported when cross compiling") |
|
else() |
|
# Leak sanitizer requires address sanitizer |
|
check_sanitizer_support("leak" supported_checks) |
|
if(NOT ${supported_checks} STREQUAL "") |
|
message(STATUS "Leak sanitizer is enabled: ${supported_checks}") |
|
add_compile_options(-fsanitize=${supported_checks}) |
|
add_link_options(-fsanitize=${supported_checks}) |
|
add_common_sanitizer_flags() |
|
else() |
|
message(STATUS "Leak sanitizer is not supported") |
|
endif() |
|
endif() |
|
endmacro() |
|
|
|
macro(add_memory_sanitizer) |
|
check_sanitizer_support("memory" supported_checks) |
|
if(NOT ${supported_checks} STREQUAL "") |
|
message(STATUS "Memory sanitizer is enabled: ${supported_checks}") |
|
add_compile_options(-fsanitize=${supported_checks}) |
|
add_link_options(-fsanitize=${supported_checks}) |
|
add_common_sanitizer_flags() |
|
|
|
check_c_compiler_flag(-fsanitize-memory-track-origins HAVE_MEMORY_TRACK_ORIGINS) |
|
if(HAVE_MEMORY_TRACK_ORIGINS) |
|
add_compile_options(-fsanitize-memory-track-origins) |
|
add_link_options(-fsanitize-memory-track-origins) |
|
endif() |
|
else() |
|
message(STATUS "Memory sanitizer is not supported") |
|
endif() |
|
endmacro() |
|
|
|
macro(add_thread_sanitizer) |
|
check_sanitizer_support("thread" supported_checks) |
|
if(NOT ${supported_checks} STREQUAL "") |
|
message(STATUS "Thread sanitizer is enabled: ${supported_checks}") |
|
add_compile_options(-fsanitize=${supported_checks}) |
|
add_link_options(-fsanitize=${supported_checks}) |
|
add_common_sanitizer_flags() |
|
else() |
|
message(STATUS "Thread sanitizer is not supported") |
|
endif() |
|
endmacro() |
|
|
|
macro(add_undefined_sanitizer) |
|
set(known_checks |
|
array-bounds |
|
bool |
|
bounds |
|
builtin |
|
enum |
|
float-cast-overflow |
|
float-divide-by-zero |
|
function |
|
integer-divide-by-zero |
|
local-bounds |
|
null |
|
nonnull-attribute |
|
pointer-overflow |
|
return |
|
returns-nonnull-attribute |
|
shift |
|
shift-base |
|
shift-exponent |
|
signed-integer-overflow |
|
undefined |
|
unsigned-integer-overflow |
|
unsigned-shift-base |
|
vla-bound |
|
vptr |
|
) |
|
|
|
# Only check for alignment sanitizer flag if unaligned access is not supported |
|
if(NOT WITH_UNALIGNED) |
|
list(APPEND known_checks alignment) |
|
endif() |
|
# Object size sanitizer has no effect at -O0 and produces compiler warning if enabled |
|
if(NOT CMAKE_C_FLAGS MATCHES "-O0") |
|
list(APPEND known_checks object-size) |
|
endif() |
|
|
|
check_sanitizer_support("${known_checks}" supported_checks) |
|
|
|
if(NOT ${supported_checks} STREQUAL "") |
|
message(STATUS "Undefined behavior sanitizer is enabled: ${supported_checks}") |
|
add_compile_options(-fsanitize=${supported_checks}) |
|
add_link_options(-fsanitize=${supported_checks}) |
|
|
|
# Group sanitizer flag -fsanitize=undefined will automatically add alignment, even if |
|
# it is not in our sanitize flag list, so we need to explicitly disable alignment sanitizing. |
|
if(WITH_UNALIGNED) |
|
add_compile_options(-fno-sanitize=alignment) |
|
endif() |
|
|
|
add_common_sanitizer_flags() |
|
else() |
|
message(STATUS "Undefined behavior sanitizer is not supported") |
|
endif() |
|
endmacro()
|
|
|