diff options
Diffstat (limited to 'cmake/3rdparty/extra-cmake-modules/modules/ECMEnableSanitizers.cmake')
-rw-r--r-- | cmake/3rdparty/extra-cmake-modules/modules/ECMEnableSanitizers.cmake | 214 |
1 files changed, 106 insertions, 108 deletions
diff --git a/cmake/3rdparty/extra-cmake-modules/modules/ECMEnableSanitizers.cmake b/cmake/3rdparty/extra-cmake-modules/modules/ECMEnableSanitizers.cmake index 4c43e99b6b..15610587bd 100644 --- a/cmake/3rdparty/extra-cmake-modules/modules/ECMEnableSanitizers.cmake +++ b/cmake/3rdparty/extra-cmake-modules/modules/ECMEnableSanitizers.cmake @@ -1,104 +1,83 @@ -#.rst: -# ECMEnableSanitizers -# ------------------- +# SPDX-FileCopyrightText: 2014 Mathieu Tarral <mathieu.tarral@gmail.com> # -# Enable compiler sanitizer flags. -# -# The following sanitizers are supported: -# -# - Address Sanitizer -# - Memory Sanitizer -# - Thread Sanitizer -# - Leak Sanitizer -# - Undefined Behaviour Sanitizer -# -# All of them are implemented in Clang, depending on your version, and -# there is an work in progress in GCC, where some of them are currently -# implemented. -# -# This module will check your current compiler version to see if it -# supports the sanitizers that you want to enable -# -# Usage -# ===== -# -# Simply add:: -# -# include(ECMEnableSanitizers) -# -# to your ``CMakeLists.txt``. Note that this module is included in -# KDECompilerSettings, so projects using that module do not need to also -# include this one. -# -# The sanitizers are not enabled by default. Instead, you must set -# ``ECM_ENABLE_SANITIZERS`` (either in your ``CMakeLists.txt`` or on the -# command line) to a semicolon-separated list of sanitizers you wish to enable. -# The options are: -# -# - address -# - memory -# - thread -# - leak -# - undefined -# - fuzzer-no-link -# - fuzzer -# -# The sanitizers "address", "memory" and "thread" are mutually exclusive. You -# cannot enable two of them in the same build. -# -# "leak" requires the "address" sanitizer. -# -# .. note:: -# -# To reduce the overhead induced by the instrumentation of the sanitizers, it -# is advised to enable compiler optimizations (``-O1`` or higher). -# -# Example -# ======= -# -# This is an example of usage:: -# -# mkdir build -# cd build -# cmake -DECM_ENABLE_SANITIZERS='address;leak;undefined' .. -# -# .. note:: -# -# Most of the sanitizers will require Clang. To enable it, use:: -# -# -DCMAKE_CXX_COMPILER=clang++ -# -# Since 1.3.0. +# SPDX-License-Identifier: BSD-3-Clause -#============================================================================= -# Copyright 2014 Mathieu Tarral <mathieu.tarral@gmail.com> -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. The name of the author may not be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#[=======================================================================[.rst: +ECMEnableSanitizers +------------------- + +Enable compiler sanitizer flags. + +The following sanitizers are supported: + +- Address Sanitizer +- Memory Sanitizer +- Thread Sanitizer +- Leak Sanitizer +- Undefined Behaviour Sanitizer + +All of them are implemented in Clang, depending on your version, and +there is an work in progress in GCC, where some of them are currently +implemented. + +This module will check your current compiler version to see if it +supports the sanitizers that you want to enable + +Usage +===== + +Simply add:: + + include(ECMEnableSanitizers) + +to your ``CMakeLists.txt``. Note that this module is included in +KDECompilerSettings, so projects using that module do not need to also +include this one. + +The sanitizers are not enabled by default. Instead, you must set +``ECM_ENABLE_SANITIZERS`` (either in your ``CMakeLists.txt`` or on the +command line) to a semicolon-separated list of sanitizers you wish to enable. +The options are: + +- address +- memory +- thread +- leak +- undefined +- fuzzer-no-link +- fuzzer + +The sanitizers "address", "memory" and "thread" are mutually exclusive. You +cannot enable two of them in the same build. + +"leak" requires the "address" sanitizer. + +.. note:: + + To reduce the overhead induced by the instrumentation of the sanitizers, it + is advised to enable compiler optimizations (``-O1`` or higher). + +Example +======= + +This is an example of usage:: + + mkdir build + cd build + cmake -DECM_ENABLE_SANITIZERS='address;leak;undefined' .. + +.. note:: + + Most of the sanitizers will require Clang. To enable it, use:: + + -DCMAKE_CXX_COMPILER=clang++ + +Since 1.3.0. +#]=======================================================================] # MACRO check_compiler_version #----------------------------- -macro (check_compiler_version gcc_required_version clang_required_version) +macro (check_compiler_version gcc_required_version clang_required_version msvc_required_version) if ( ( CMAKE_CXX_COMPILER_ID MATCHES "GNU" @@ -111,12 +90,19 @@ macro (check_compiler_version gcc_required_version clang_required_version) AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${clang_required_version} ) + OR + ( + CMAKE_CXX_COMPILER_ID MATCHES "MSVC" + AND + CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${msvc_required_version} + ) ) # error ! message(FATAL_ERROR "You ask to enable the sanitizer ${CUR_SANITIZER}, but your compiler ${CMAKE_CXX_COMPILER_ID} version ${CMAKE_CXX_COMPILER_VERSION} does not support it ! - You should use at least GCC ${gcc_required_version} or Clang ${clang_required_version} + You should use at least GCC ${gcc_required_version}, Clang ${clang_required_version} + or MSVC ${msvc_required_version} (99.99 means not implemented yet)") endif () endmacro () @@ -125,29 +111,33 @@ endmacro () #------------------------------ macro (enable_sanitizer_flags sanitize_option) if (${sanitize_option} MATCHES "address") - check_compiler_version("4.8" "3.1") - set(XSAN_COMPILE_FLAGS "-fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls") - set(XSAN_LINKER_FLAGS "asan") + check_compiler_version("4.8" "3.1" "19.28") + if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC") + set(XSAN_COMPILE_FLAGS "-fsanitize=address") + else() + set(XSAN_COMPILE_FLAGS "-fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls") + set(XSAN_LINKER_FLAGS "asan") + endif() elseif (${sanitize_option} MATCHES "thread") - check_compiler_version("4.8" "3.1") + check_compiler_version("4.8" "3.1" "99.99") set(XSAN_COMPILE_FLAGS "-fsanitize=thread") set(XSAN_LINKER_FLAGS "tsan") elseif (${sanitize_option} MATCHES "memory") - check_compiler_version("99.99" "3.1") + check_compiler_version("99.99" "3.1" "99.99") set(XSAN_COMPILE_FLAGS "-fsanitize=memory") elseif (${sanitize_option} MATCHES "leak") - check_compiler_version("4.9" "3.4") + check_compiler_version("4.9" "3.4" "99.99") set(XSAN_COMPILE_FLAGS "-fsanitize=leak") set(XSAN_LINKER_FLAGS "lsan") elseif (${sanitize_option} MATCHES "undefined") - check_compiler_version("4.9" "3.1") + check_compiler_version("4.9" "3.1" "99.99") set(XSAN_COMPILE_FLAGS "-fsanitize=undefined -fsanitize=float-divide-by-zero -fno-omit-frame-pointer -fno-optimize-sibling-calls") elseif (${sanitize_option} MATCHES "fuzzer-no-link") - check_compiler_version("99.99" "6.0") + check_compiler_version("99.99" "6.0" "99.99") set(XSAN_COMPILE_FLAGS "-fsanitize=fuzzer-no-link") set(XSAN_LINKER_FLAGS "-fsanitize=fuzzer-no-link") elseif (${sanitize_option} MATCHES "fuzzer") - check_compiler_version("99.99" "6.0") + check_compiler_version("99.99" "6.0" "99.99") set(XSAN_COMPILE_FLAGS "-fsanitize=fuzzer") else () message(FATAL_ERROR "Compiler sanitizer option \"${sanitize_option}\" not supported.") @@ -155,7 +145,7 @@ macro (enable_sanitizer_flags sanitize_option) endmacro () if (ECM_ENABLE_SANITIZERS) - if (CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + if (CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "MSVC") # for each element of the ECM_ENABLE_SANITIZERS list foreach ( CUR_SANITIZER ${ECM_ENABLE_SANITIZERS} ) # lowercase filter @@ -168,7 +158,15 @@ if (ECM_ENABLE_SANITIZERS) endif() set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${XSAN_COMPILE_FLAGS}" ) if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") - link_libraries(${XSAN_LINKER_FLAGS}) + string(JOIN "" linker_flags + "$<" + "$<NOT:" + "$<BOOL:$<TARGET_PROPERTY:SKIP_SANITIZER>>" + ">:" + "${XSAN_LINKER_FLAGS}" + ">" + ) + link_libraries("${linker_flags}") endif() if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") string(REPLACE "-Wl,--no-undefined" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}") |