The open source OpenXR runtime
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

cmake: Add address sanitizers

authored by

Moses Turner and committed by
Jakob Bornecrantz
8c9483d1 a6bdf92f

+556
+3
CMakeLists.txt
··· 20 20 # Dependencies 21 21 ### 22 22 list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") 23 + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/sanitizers") 23 24 include(CMakeDependentOption) 24 25 include(SPIR-V) 25 26 include(GNUInstallDirs) ··· 62 63 find_package(OpenGLES COMPONENTS V3) 63 64 find_package(LeapV2) 64 65 66 + #https://github.com/arsenm/sanitizers-cmake 67 + find_package(Sanitizers) 65 68 66 69 add_library(xrt-pthreads INTERFACE) 67 70 if(WIN32)
+59
cmake/sanitizers/FindASan.cmake
··· 1 + # The MIT License (MIT) 2 + # 3 + # Copyright (c) 4 + # 2013 Matthew Arsenault 5 + # 2015-2016 RWTH Aachen University, Federal Republic of Germany 6 + # 7 + # Permission is hereby granted, free of charge, to any person obtaining a copy 8 + # of this software and associated documentation files (the "Software"), to deal 9 + # in the Software without restriction, including without limitation the rights 10 + # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 + # copies of the Software, and to permit persons to whom the Software is 12 + # furnished to do so, subject to the following conditions: 13 + # 14 + # The above copyright notice and this permission notice shall be included in all 15 + # copies or substantial portions of the Software. 16 + # 17 + # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 + # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 + # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 + # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 + # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 + # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 + # SOFTWARE. 24 + 25 + option(SANITIZE_ADDRESS "Enable AddressSanitizer for sanitized targets." Off) 26 + 27 + set(FLAG_CANDIDATES 28 + # Clang 3.2+ use this version. The no-omit-frame-pointer option is optional. 29 + "-g -fsanitize=address -fno-omit-frame-pointer" 30 + "-g -fsanitize=address" 31 + 32 + # Older deprecated flag for ASan 33 + "-g -faddress-sanitizer" 34 + ) 35 + 36 + 37 + if (SANITIZE_ADDRESS AND (SANITIZE_THREAD OR SANITIZE_MEMORY)) 38 + message(FATAL_ERROR "AddressSanitizer is not compatible with " 39 + "ThreadSanitizer or MemorySanitizer.") 40 + endif () 41 + 42 + 43 + include(sanitize-helpers) 44 + 45 + if (SANITIZE_ADDRESS) 46 + sanitizer_check_compiler_flags("${FLAG_CANDIDATES}" "AddressSanitizer" 47 + "ASan") 48 + 49 + find_program(ASan_WRAPPER "asan-wrapper" PATHS ${CMAKE_MODULE_PATH}) 50 + mark_as_advanced(ASan_WRAPPER) 51 + endif () 52 + 53 + function (add_sanitize_address TARGET) 54 + if (NOT SANITIZE_ADDRESS) 55 + return() 56 + endif () 57 + 58 + sanitizer_add_flags(${TARGET} "AddressSanitizer" "ASan") 59 + endfunction ()
+57
cmake/sanitizers/FindMSan.cmake
··· 1 + # The MIT License (MIT) 2 + # 3 + # Copyright (c) 4 + # 2013 Matthew Arsenault 5 + # 2015-2016 RWTH Aachen University, Federal Republic of Germany 6 + # 7 + # Permission is hereby granted, free of charge, to any person obtaining a copy 8 + # of this software and associated documentation files (the "Software"), to deal 9 + # in the Software without restriction, including without limitation the rights 10 + # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 + # copies of the Software, and to permit persons to whom the Software is 12 + # furnished to do so, subject to the following conditions: 13 + # 14 + # The above copyright notice and this permission notice shall be included in all 15 + # copies or substantial portions of the Software. 16 + # 17 + # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 + # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 + # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 + # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 + # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 + # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 + # SOFTWARE. 24 + 25 + option(SANITIZE_MEMORY "Enable MemorySanitizer for sanitized targets." Off) 26 + 27 + set(FLAG_CANDIDATES 28 + "-g -fsanitize=memory" 29 + ) 30 + 31 + 32 + include(sanitize-helpers) 33 + 34 + if (SANITIZE_MEMORY) 35 + if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Linux") 36 + message(WARNING "MemorySanitizer disabled for target ${TARGET} because " 37 + "MemorySanitizer is supported for Linux systems only.") 38 + set(SANITIZE_MEMORY Off CACHE BOOL 39 + "Enable MemorySanitizer for sanitized targets." FORCE) 40 + elseif (NOT ${CMAKE_SIZEOF_VOID_P} EQUAL 8) 41 + message(WARNING "MemorySanitizer disabled for target ${TARGET} because " 42 + "MemorySanitizer is supported for 64bit systems only.") 43 + set(SANITIZE_MEMORY Off CACHE BOOL 44 + "Enable MemorySanitizer for sanitized targets." FORCE) 45 + else () 46 + sanitizer_check_compiler_flags("${FLAG_CANDIDATES}" "MemorySanitizer" 47 + "MSan") 48 + endif () 49 + endif () 50 + 51 + function (add_sanitize_memory TARGET) 52 + if (NOT SANITIZE_MEMORY) 53 + return() 54 + endif () 55 + 56 + sanitizer_add_flags(${TARGET} "MemorySanitizer" "MSan") 57 + endfunction ()
+94
cmake/sanitizers/FindSanitizers.cmake
··· 1 + # The MIT License (MIT) 2 + # 3 + # Copyright (c) 4 + # 2013 Matthew Arsenault 5 + # 2015-2016 RWTH Aachen University, Federal Republic of Germany 6 + # 7 + # Permission is hereby granted, free of charge, to any person obtaining a copy 8 + # of this software and associated documentation files (the "Software"), to deal 9 + # in the Software without restriction, including without limitation the rights 10 + # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 + # copies of the Software, and to permit persons to whom the Software is 12 + # furnished to do so, subject to the following conditions: 13 + # 14 + # The above copyright notice and this permission notice shall be included in all 15 + # copies or substantial portions of the Software. 16 + # 17 + # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 + # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 + # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 + # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 + # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 + # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 + # SOFTWARE. 24 + 25 + # If any of the used compiler is a GNU compiler, add a second option to static 26 + # link against the sanitizers. 27 + option(SANITIZE_LINK_STATIC "Try to link static against sanitizers." Off) 28 + 29 + 30 + 31 + 32 + set(FIND_QUIETLY_FLAG "") 33 + if (DEFINED Sanitizers_FIND_QUIETLY) 34 + set(FIND_QUIETLY_FLAG "QUIET") 35 + endif () 36 + 37 + find_package(ASan ${FIND_QUIETLY_FLAG}) 38 + find_package(TSan ${FIND_QUIETLY_FLAG}) 39 + find_package(MSan ${FIND_QUIETLY_FLAG}) 40 + find_package(UBSan ${FIND_QUIETLY_FLAG}) 41 + 42 + 43 + 44 + 45 + function(sanitizer_add_blacklist_file FILE) 46 + if(NOT IS_ABSOLUTE ${FILE}) 47 + set(FILE "${CMAKE_CURRENT_SOURCE_DIR}/${FILE}") 48 + endif() 49 + get_filename_component(FILE "${FILE}" REALPATH) 50 + 51 + sanitizer_check_compiler_flags("-fsanitize-blacklist=${FILE}" 52 + "SanitizerBlacklist" "SanBlist") 53 + endfunction() 54 + 55 + function(add_sanitizers ...) 56 + # If no sanitizer is enabled, return immediately. 57 + if (NOT (SANITIZE_ADDRESS OR SANITIZE_MEMORY OR SANITIZE_THREAD OR 58 + SANITIZE_UNDEFINED)) 59 + return() 60 + endif () 61 + 62 + foreach (TARGET ${ARGV}) 63 + # Check if this target will be compiled by exactly one compiler. Other- 64 + # wise sanitizers can't be used and a warning should be printed once. 65 + get_target_property(TARGET_TYPE ${TARGET} TYPE) 66 + if (TARGET_TYPE STREQUAL "INTERFACE_LIBRARY") 67 + message(WARNING "Can't use any sanitizers for target ${TARGET}, " 68 + "because it is an interface library and cannot be " 69 + "compiled directly.") 70 + return() 71 + endif () 72 + sanitizer_target_compilers(${TARGET} TARGET_COMPILER) 73 + list(LENGTH TARGET_COMPILER NUM_COMPILERS) 74 + if (NUM_COMPILERS GREATER 1) 75 + message(WARNING "Can't use any sanitizers for target ${TARGET}, " 76 + "because it will be compiled by incompatible compilers. " 77 + "Target will be compiled without sanitizers.") 78 + return() 79 + 80 + # If the target is compiled by no or no known compiler, give a warning. 81 + elseif (NUM_COMPILERS EQUAL 0) 82 + message(WARNING "Sanitizers for target ${TARGET} may not be" 83 + " usable, because it uses no or an unknown compiler. " 84 + "This is a false warning for targets using only " 85 + "object lib(s) as input.") 86 + endif () 87 + 88 + # Add sanitizers for target. 89 + add_sanitize_address(${TARGET}) 90 + add_sanitize_thread(${TARGET}) 91 + add_sanitize_memory(${TARGET}) 92 + add_sanitize_undefined(${TARGET}) 93 + endforeach () 94 + endfunction(add_sanitizers)
+65
cmake/sanitizers/FindTSan.cmake
··· 1 + # The MIT License (MIT) 2 + # 3 + # Copyright (c) 4 + # 2013 Matthew Arsenault 5 + # 2015-2016 RWTH Aachen University, Federal Republic of Germany 6 + # 7 + # Permission is hereby granted, free of charge, to any person obtaining a copy 8 + # of this software and associated documentation files (the "Software"), to deal 9 + # in the Software without restriction, including without limitation the rights 10 + # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 + # copies of the Software, and to permit persons to whom the Software is 12 + # furnished to do so, subject to the following conditions: 13 + # 14 + # The above copyright notice and this permission notice shall be included in all 15 + # copies or substantial portions of the Software. 16 + # 17 + # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 + # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 + # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 + # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 + # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 + # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 + # SOFTWARE. 24 + 25 + option(SANITIZE_THREAD "Enable ThreadSanitizer for sanitized targets." Off) 26 + 27 + set(FLAG_CANDIDATES 28 + "-g -fsanitize=thread" 29 + ) 30 + 31 + 32 + # ThreadSanitizer is not compatible with MemorySanitizer. 33 + if (SANITIZE_THREAD AND SANITIZE_MEMORY) 34 + message(FATAL_ERROR "ThreadSanitizer is not compatible with " 35 + "MemorySanitizer.") 36 + endif () 37 + 38 + 39 + include(sanitize-helpers) 40 + 41 + if (SANITIZE_THREAD) 42 + if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND 43 + NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") 44 + message(WARNING "ThreadSanitizer disabled for target ${TARGET} because " 45 + "ThreadSanitizer is supported for Linux systems and macOS only.") 46 + set(SANITIZE_THREAD Off CACHE BOOL 47 + "Enable ThreadSanitizer for sanitized targets." FORCE) 48 + elseif (NOT ${CMAKE_SIZEOF_VOID_P} EQUAL 8) 49 + message(WARNING "ThreadSanitizer disabled for target ${TARGET} because " 50 + "ThreadSanitizer is supported for 64bit systems only.") 51 + set(SANITIZE_THREAD Off CACHE BOOL 52 + "Enable ThreadSanitizer for sanitized targets." FORCE) 53 + else () 54 + sanitizer_check_compiler_flags("${FLAG_CANDIDATES}" "ThreadSanitizer" 55 + "TSan") 56 + endif () 57 + endif () 58 + 59 + function (add_sanitize_thread TARGET) 60 + if (NOT SANITIZE_THREAD) 61 + return() 62 + endif () 63 + 64 + sanitizer_add_flags(${TARGET} "ThreadSanitizer" "TSan") 65 + endfunction ()
+46
cmake/sanitizers/FindUBSan.cmake
··· 1 + # The MIT License (MIT) 2 + # 3 + # Copyright (c) 4 + # 2013 Matthew Arsenault 5 + # 2015-2016 RWTH Aachen University, Federal Republic of Germany 6 + # 7 + # Permission is hereby granted, free of charge, to any person obtaining a copy 8 + # of this software and associated documentation files (the "Software"), to deal 9 + # in the Software without restriction, including without limitation the rights 10 + # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 + # copies of the Software, and to permit persons to whom the Software is 12 + # furnished to do so, subject to the following conditions: 13 + # 14 + # The above copyright notice and this permission notice shall be included in all 15 + # copies or substantial portions of the Software. 16 + # 17 + # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 + # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 + # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 + # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 + # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 + # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 + # SOFTWARE. 24 + 25 + option(SANITIZE_UNDEFINED 26 + "Enable UndefinedBehaviorSanitizer for sanitized targets." Off) 27 + 28 + set(FLAG_CANDIDATES 29 + "-g -fsanitize=undefined" 30 + ) 31 + 32 + 33 + include(sanitize-helpers) 34 + 35 + if (SANITIZE_UNDEFINED) 36 + sanitizer_check_compiler_flags("${FLAG_CANDIDATES}" 37 + "UndefinedBehaviorSanitizer" "UBSan") 38 + endif () 39 + 40 + function (add_sanitize_undefined TARGET) 41 + if (NOT SANITIZE_UNDEFINED) 42 + return() 43 + endif () 44 + 45 + sanitizer_add_flags(${TARGET} "UndefinedBehaviorSanitizer" "UBSan") 46 + endfunction ()
+55
cmake/sanitizers/asan-wrapper
··· 1 + #!/bin/sh 2 + 3 + # The MIT License (MIT) 4 + # 5 + # Copyright (c) 6 + # 2013 Matthew Arsenault 7 + # 2015-2016 RWTH Aachen University, Federal Republic of Germany 8 + # 9 + # Permission is hereby granted, free of charge, to any person obtaining a copy 10 + # of this software and associated documentation files (the "Software"), to deal 11 + # in the Software without restriction, including without limitation the rights 12 + # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 + # copies of the Software, and to permit persons to whom the Software is 14 + # furnished to do so, subject to the following conditions: 15 + # 16 + # The above copyright notice and this permission notice shall be included in all 17 + # copies or substantial portions of the Software. 18 + # 19 + # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 + # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 + # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 + # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 + # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 + # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 + # SOFTWARE. 26 + 27 + # This script is a wrapper for AddressSanitizer. In some special cases you need 28 + # to preload AddressSanitizer to avoid error messages - e.g. if you're 29 + # preloading another library to your application. At the moment this script will 30 + # only do something, if we're running on a Linux platform. OSX might not be 31 + # affected. 32 + 33 + 34 + # Exit immediately, if platform is not Linux. 35 + if [ "$(uname)" != "Linux" ] 36 + then 37 + exec $@ 38 + fi 39 + 40 + 41 + # Get the used libasan of the application ($1). If a libasan was found, it will 42 + # be prepended to LD_PRELOAD. 43 + libasan=$(ldd $1 | grep libasan | sed "s/^[[:space:]]//" | cut -d' ' -f1) 44 + if [ -n "$libasan" ] 45 + then 46 + if [ -n "$LD_PRELOAD" ] 47 + then 48 + export LD_PRELOAD="$libasan:$LD_PRELOAD" 49 + else 50 + export LD_PRELOAD="$libasan" 51 + fi 52 + fi 53 + 54 + # Execute the application. 55 + exec $@
+177
cmake/sanitizers/sanitize-helpers.cmake
··· 1 + # The MIT License (MIT) 2 + # 3 + # Copyright (c) 4 + # 2013 Matthew Arsenault 5 + # 2015-2016 RWTH Aachen University, Federal Republic of Germany 6 + # 7 + # Permission is hereby granted, free of charge, to any person obtaining a copy 8 + # of this software and associated documentation files (the "Software"), to deal 9 + # in the Software without restriction, including without limitation the rights 10 + # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 + # copies of the Software, and to permit persons to whom the Software is 12 + # furnished to do so, subject to the following conditions: 13 + # 14 + # The above copyright notice and this permission notice shall be included in all 15 + # copies or substantial portions of the Software. 16 + # 17 + # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 + # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 + # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 + # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 + # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 + # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 + # SOFTWARE. 24 + 25 + # Helper function to get the language of a source file. 26 + function (sanitizer_lang_of_source FILE RETURN_VAR) 27 + get_filename_component(LONGEST_EXT "${FILE}" EXT) 28 + # If extension is empty return. This can happen for extensionless headers 29 + if("${LONGEST_EXT}" STREQUAL "") 30 + set(${RETURN_VAR} "" PARENT_SCOPE) 31 + return() 32 + endif() 33 + # Get shortest extension as some files can have dot in their names 34 + string(REGEX REPLACE "^.*(\\.[^.]+)$" "\\1" FILE_EXT ${LONGEST_EXT}) 35 + string(TOLOWER "${FILE_EXT}" FILE_EXT) 36 + string(SUBSTRING "${FILE_EXT}" 1 -1 FILE_EXT) 37 + 38 + get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) 39 + foreach (LANG ${ENABLED_LANGUAGES}) 40 + list(FIND CMAKE_${LANG}_SOURCE_FILE_EXTENSIONS "${FILE_EXT}" TEMP) 41 + if (NOT ${TEMP} EQUAL -1) 42 + set(${RETURN_VAR} "${LANG}" PARENT_SCOPE) 43 + return() 44 + endif () 45 + endforeach() 46 + 47 + set(${RETURN_VAR} "" PARENT_SCOPE) 48 + endfunction () 49 + 50 + 51 + # Helper function to get compilers used by a target. 52 + function (sanitizer_target_compilers TARGET RETURN_VAR) 53 + # Check if all sources for target use the same compiler. If a target uses 54 + # e.g. C and Fortran mixed and uses different compilers (e.g. clang and 55 + # gfortran) this can trigger huge problems, because different compilers may 56 + # use different implementations for sanitizers. 57 + set(BUFFER "") 58 + get_target_property(TSOURCES ${TARGET} SOURCES) 59 + foreach (FILE ${TSOURCES}) 60 + # If expression was found, FILE is a generator-expression for an object 61 + # library. Object libraries will be ignored. 62 + string(REGEX MATCH "TARGET_OBJECTS:([^ >]+)" _file ${FILE}) 63 + if ("${_file}" STREQUAL "") 64 + sanitizer_lang_of_source(${FILE} LANG) 65 + if (LANG) 66 + list(APPEND BUFFER ${CMAKE_${LANG}_COMPILER_ID}) 67 + endif () 68 + endif () 69 + endforeach () 70 + 71 + list(REMOVE_DUPLICATES BUFFER) 72 + set(${RETURN_VAR} "${BUFFER}" PARENT_SCOPE) 73 + endfunction () 74 + 75 + 76 + # Helper function to check compiler flags for language compiler. 77 + function (sanitizer_check_compiler_flag FLAG LANG VARIABLE) 78 + if (${LANG} STREQUAL "C") 79 + include(CheckCCompilerFlag) 80 + check_c_compiler_flag("${FLAG}" ${VARIABLE}) 81 + 82 + elseif (${LANG} STREQUAL "CXX") 83 + include(CheckCXXCompilerFlag) 84 + check_cxx_compiler_flag("${FLAG}" ${VARIABLE}) 85 + 86 + elseif (${LANG} STREQUAL "Fortran") 87 + # CheckFortranCompilerFlag was introduced in CMake 3.x. To be compatible 88 + # with older Cmake versions, we will check if this module is present 89 + # before we use it. Otherwise we will define Fortran coverage support as 90 + # not available. 91 + include(CheckFortranCompilerFlag OPTIONAL RESULT_VARIABLE INCLUDED) 92 + if (INCLUDED) 93 + check_fortran_compiler_flag("${FLAG}" ${VARIABLE}) 94 + elseif (NOT CMAKE_REQUIRED_QUIET) 95 + message(STATUS "Performing Test ${VARIABLE}") 96 + message(STATUS "Performing Test ${VARIABLE}" 97 + " - Failed (Check not supported)") 98 + endif () 99 + endif() 100 + endfunction () 101 + 102 + 103 + # Helper function to test compiler flags. 104 + function (sanitizer_check_compiler_flags FLAG_CANDIDATES NAME PREFIX) 105 + set(CMAKE_REQUIRED_QUIET ${${PREFIX}_FIND_QUIETLY}) 106 + 107 + get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) 108 + foreach (LANG ${ENABLED_LANGUAGES}) 109 + # Sanitizer flags are not dependend on language, but the used compiler. 110 + # So instead of searching flags foreach language, search flags foreach 111 + # compiler used. 112 + set(COMPILER ${CMAKE_${LANG}_COMPILER_ID}) 113 + if (NOT DEFINED ${PREFIX}_${COMPILER}_FLAGS) 114 + foreach (FLAG ${FLAG_CANDIDATES}) 115 + if(NOT CMAKE_REQUIRED_QUIET) 116 + message(STATUS "Try ${COMPILER} ${NAME} flag = [${FLAG}]") 117 + endif() 118 + 119 + set(CMAKE_REQUIRED_FLAGS "${FLAG}") 120 + unset(${PREFIX}_FLAG_DETECTED CACHE) 121 + sanitizer_check_compiler_flag("${FLAG}" ${LANG} 122 + ${PREFIX}_FLAG_DETECTED) 123 + 124 + if (${PREFIX}_FLAG_DETECTED) 125 + # If compiler is a GNU compiler, search for static flag, if 126 + # SANITIZE_LINK_STATIC is enabled. 127 + if (SANITIZE_LINK_STATIC AND (${COMPILER} STREQUAL "GNU")) 128 + string(TOLOWER ${PREFIX} PREFIX_lower) 129 + sanitizer_check_compiler_flag( 130 + "-static-lib${PREFIX_lower}" ${LANG} 131 + ${PREFIX}_STATIC_FLAG_DETECTED) 132 + 133 + if (${PREFIX}_STATIC_FLAG_DETECTED) 134 + set(FLAG "-static-lib${PREFIX_lower} ${FLAG}") 135 + endif () 136 + endif () 137 + 138 + set(${PREFIX}_${COMPILER}_FLAGS "${FLAG}" CACHE STRING 139 + "${NAME} flags for ${COMPILER} compiler.") 140 + mark_as_advanced(${PREFIX}_${COMPILER}_FLAGS) 141 + break() 142 + endif () 143 + endforeach () 144 + 145 + if (NOT ${PREFIX}_FLAG_DETECTED) 146 + set(${PREFIX}_${COMPILER}_FLAGS "" CACHE STRING 147 + "${NAME} flags for ${COMPILER} compiler.") 148 + mark_as_advanced(${PREFIX}_${COMPILER}_FLAGS) 149 + 150 + message(WARNING "${NAME} is not available for ${COMPILER} " 151 + "compiler. Targets using this compiler will be " 152 + "compiled without ${NAME}.") 153 + endif () 154 + endif () 155 + endforeach () 156 + endfunction () 157 + 158 + 159 + # Helper to assign sanitizer flags for TARGET. 160 + function (sanitizer_add_flags TARGET NAME PREFIX) 161 + # Get list of compilers used by target and check, if sanitizer is available 162 + # for this target. Other compiler checks like check for conflicting 163 + # compilers will be done in add_sanitizers function. 164 + sanitizer_target_compilers(${TARGET} TARGET_COMPILER) 165 + list(LENGTH TARGET_COMPILER NUM_COMPILERS) 166 + if ("${${PREFIX}_${TARGET_COMPILER}_FLAGS}" STREQUAL "") 167 + return() 168 + endif() 169 + 170 + # Set compile- and link-flags for target. 171 + set_property(TARGET ${TARGET} APPEND_STRING 172 + PROPERTY COMPILE_FLAGS " ${${PREFIX}_${TARGET_COMPILER}_FLAGS}") 173 + set_property(TARGET ${TARGET} APPEND_STRING 174 + PROPERTY COMPILE_FLAGS " ${SanBlist_${TARGET_COMPILER}_FLAGS}") 175 + set_property(TARGET ${TARGET} APPEND_STRING 176 + PROPERTY LINK_FLAGS " ${${PREFIX}_${TARGET_COMPILER}_FLAGS}") 177 + endfunction ()