blob: 82ad0fd3694e4f193fa5ef406aca9e61dfce053a [file] [log] [blame]
# detect-sanitizer.cmake -- Detect supported compiler sanitizer flags
# Licensed under the Zlib license, see LICENSE.md for details
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; }" HAS_SANITIZER_${check}
FAIL_REGEX "not supported|unrecognized command|unknown option")
set(CMAKE_REQUIRED_FLAGS)
if(HAS_SANITIZER_${check})
set(available_checks ${compile_checks})
endif()
endforeach()
set(${supported_checks} ${available_checks})
endmacro()
macro(add_memory_sanitizer_check)
check_sanitizer_support("memory" supported_checks)
if(NOT ${supported_checks} STREQUAL "")
message(STATUS "Memory sanitizer is enabled")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=${supported_checks}")
else()
message(STATUS "Memory sanitizer is not supported")
endif()
endmacro()
macro(add_sanitizer_checks)
set(known_checks
address
array-bounds
bool
bounds
builtin
enum
float-divide-by-zero
function
integer-divide-by-zero
null
nonnull-attribute
object-size
pointer-compare # Depends on 'address'
pointer-overflow
pointer-subtract # Depends on 'address'
return
returns-nonnull-attribute
shift
shift-base
shift-exponent
signed-integer-overflow
undefined
unsigned-integer-overflow
vla-bound
vptr
)
# Only check for leak sanitizer if not cross-compiling due to qemu crash
if(NOT CMAKE_CROSSCOMPILING_EMULATOR)
list(APPEND known_checks leak)
endif()
# Only check for alignment sanitizer flag if unaligned access is not supported
if(NOT UNALIGNED_OK)
list(APPEND known_checks alignment)
endif()
check_sanitizer_support("${known_checks}" supported_checks)
if(NOT ${supported_checks} STREQUAL "")
message(STATUS "Supported sanitizers checks are enabled: ${supported_checks}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -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(UNALIGNED_OK)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-sanitize=alignment")
endif()
else()
message(STATUS "Sanitizer checks are not supported")
endif()
endmacro()