···11+# The MIT License (MIT)
22+#
33+# Copyright (c)
44+# 2013 Matthew Arsenault
55+# 2015-2016 RWTH Aachen University, Federal Republic of Germany
66+#
77+# Permission is hereby granted, free of charge, to any person obtaining a copy
88+# of this software and associated documentation files (the "Software"), to deal
99+# in the Software without restriction, including without limitation the rights
1010+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1111+# copies of the Software, and to permit persons to whom the Software is
1212+# furnished to do so, subject to the following conditions:
1313+#
1414+# The above copyright notice and this permission notice shall be included in all
1515+# copies or substantial portions of the Software.
1616+#
1717+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1818+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1919+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2020+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2121+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2222+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2323+# SOFTWARE.
2424+2525+option(SANITIZE_ADDRESS "Enable AddressSanitizer for sanitized targets." Off)
2626+2727+set(FLAG_CANDIDATES
2828+ # Clang 3.2+ use this version. The no-omit-frame-pointer option is optional.
2929+ "-g -fsanitize=address -fno-omit-frame-pointer"
3030+ "-g -fsanitize=address"
3131+3232+ # Older deprecated flag for ASan
3333+ "-g -faddress-sanitizer"
3434+)
3535+3636+3737+if (SANITIZE_ADDRESS AND (SANITIZE_THREAD OR SANITIZE_MEMORY))
3838+ message(FATAL_ERROR "AddressSanitizer is not compatible with "
3939+ "ThreadSanitizer or MemorySanitizer.")
4040+endif ()
4141+4242+4343+include(sanitize-helpers)
4444+4545+if (SANITIZE_ADDRESS)
4646+ sanitizer_check_compiler_flags("${FLAG_CANDIDATES}" "AddressSanitizer"
4747+ "ASan")
4848+4949+ find_program(ASan_WRAPPER "asan-wrapper" PATHS ${CMAKE_MODULE_PATH})
5050+ mark_as_advanced(ASan_WRAPPER)
5151+endif ()
5252+5353+function (add_sanitize_address TARGET)
5454+ if (NOT SANITIZE_ADDRESS)
5555+ return()
5656+ endif ()
5757+5858+ sanitizer_add_flags(${TARGET} "AddressSanitizer" "ASan")
5959+endfunction ()
+57
cmake/sanitizers/FindMSan.cmake
···11+# The MIT License (MIT)
22+#
33+# Copyright (c)
44+# 2013 Matthew Arsenault
55+# 2015-2016 RWTH Aachen University, Federal Republic of Germany
66+#
77+# Permission is hereby granted, free of charge, to any person obtaining a copy
88+# of this software and associated documentation files (the "Software"), to deal
99+# in the Software without restriction, including without limitation the rights
1010+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1111+# copies of the Software, and to permit persons to whom the Software is
1212+# furnished to do so, subject to the following conditions:
1313+#
1414+# The above copyright notice and this permission notice shall be included in all
1515+# copies or substantial portions of the Software.
1616+#
1717+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1818+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1919+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2020+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2121+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2222+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2323+# SOFTWARE.
2424+2525+option(SANITIZE_MEMORY "Enable MemorySanitizer for sanitized targets." Off)
2626+2727+set(FLAG_CANDIDATES
2828+ "-g -fsanitize=memory"
2929+)
3030+3131+3232+include(sanitize-helpers)
3333+3434+if (SANITIZE_MEMORY)
3535+ if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
3636+ message(WARNING "MemorySanitizer disabled for target ${TARGET} because "
3737+ "MemorySanitizer is supported for Linux systems only.")
3838+ set(SANITIZE_MEMORY Off CACHE BOOL
3939+ "Enable MemorySanitizer for sanitized targets." FORCE)
4040+ elseif (NOT ${CMAKE_SIZEOF_VOID_P} EQUAL 8)
4141+ message(WARNING "MemorySanitizer disabled for target ${TARGET} because "
4242+ "MemorySanitizer is supported for 64bit systems only.")
4343+ set(SANITIZE_MEMORY Off CACHE BOOL
4444+ "Enable MemorySanitizer for sanitized targets." FORCE)
4545+ else ()
4646+ sanitizer_check_compiler_flags("${FLAG_CANDIDATES}" "MemorySanitizer"
4747+ "MSan")
4848+ endif ()
4949+endif ()
5050+5151+function (add_sanitize_memory TARGET)
5252+ if (NOT SANITIZE_MEMORY)
5353+ return()
5454+ endif ()
5555+5656+ sanitizer_add_flags(${TARGET} "MemorySanitizer" "MSan")
5757+endfunction ()
+94
cmake/sanitizers/FindSanitizers.cmake
···11+# The MIT License (MIT)
22+#
33+# Copyright (c)
44+# 2013 Matthew Arsenault
55+# 2015-2016 RWTH Aachen University, Federal Republic of Germany
66+#
77+# Permission is hereby granted, free of charge, to any person obtaining a copy
88+# of this software and associated documentation files (the "Software"), to deal
99+# in the Software without restriction, including without limitation the rights
1010+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1111+# copies of the Software, and to permit persons to whom the Software is
1212+# furnished to do so, subject to the following conditions:
1313+#
1414+# The above copyright notice and this permission notice shall be included in all
1515+# copies or substantial portions of the Software.
1616+#
1717+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1818+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1919+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2020+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2121+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2222+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2323+# SOFTWARE.
2424+2525+# If any of the used compiler is a GNU compiler, add a second option to static
2626+# link against the sanitizers.
2727+option(SANITIZE_LINK_STATIC "Try to link static against sanitizers." Off)
2828+2929+3030+3131+3232+set(FIND_QUIETLY_FLAG "")
3333+if (DEFINED Sanitizers_FIND_QUIETLY)
3434+ set(FIND_QUIETLY_FLAG "QUIET")
3535+endif ()
3636+3737+find_package(ASan ${FIND_QUIETLY_FLAG})
3838+find_package(TSan ${FIND_QUIETLY_FLAG})
3939+find_package(MSan ${FIND_QUIETLY_FLAG})
4040+find_package(UBSan ${FIND_QUIETLY_FLAG})
4141+4242+4343+4444+4545+function(sanitizer_add_blacklist_file FILE)
4646+ if(NOT IS_ABSOLUTE ${FILE})
4747+ set(FILE "${CMAKE_CURRENT_SOURCE_DIR}/${FILE}")
4848+ endif()
4949+ get_filename_component(FILE "${FILE}" REALPATH)
5050+5151+ sanitizer_check_compiler_flags("-fsanitize-blacklist=${FILE}"
5252+ "SanitizerBlacklist" "SanBlist")
5353+endfunction()
5454+5555+function(add_sanitizers ...)
5656+ # If no sanitizer is enabled, return immediately.
5757+ if (NOT (SANITIZE_ADDRESS OR SANITIZE_MEMORY OR SANITIZE_THREAD OR
5858+ SANITIZE_UNDEFINED))
5959+ return()
6060+ endif ()
6161+6262+ foreach (TARGET ${ARGV})
6363+ # Check if this target will be compiled by exactly one compiler. Other-
6464+ # wise sanitizers can't be used and a warning should be printed once.
6565+ get_target_property(TARGET_TYPE ${TARGET} TYPE)
6666+ if (TARGET_TYPE STREQUAL "INTERFACE_LIBRARY")
6767+ message(WARNING "Can't use any sanitizers for target ${TARGET}, "
6868+ "because it is an interface library and cannot be "
6969+ "compiled directly.")
7070+ return()
7171+ endif ()
7272+ sanitizer_target_compilers(${TARGET} TARGET_COMPILER)
7373+ list(LENGTH TARGET_COMPILER NUM_COMPILERS)
7474+ if (NUM_COMPILERS GREATER 1)
7575+ message(WARNING "Can't use any sanitizers for target ${TARGET}, "
7676+ "because it will be compiled by incompatible compilers. "
7777+ "Target will be compiled without sanitizers.")
7878+ return()
7979+8080+ # If the target is compiled by no or no known compiler, give a warning.
8181+ elseif (NUM_COMPILERS EQUAL 0)
8282+ message(WARNING "Sanitizers for target ${TARGET} may not be"
8383+ " usable, because it uses no or an unknown compiler. "
8484+ "This is a false warning for targets using only "
8585+ "object lib(s) as input.")
8686+ endif ()
8787+8888+ # Add sanitizers for target.
8989+ add_sanitize_address(${TARGET})
9090+ add_sanitize_thread(${TARGET})
9191+ add_sanitize_memory(${TARGET})
9292+ add_sanitize_undefined(${TARGET})
9393+ endforeach ()
9494+endfunction(add_sanitizers)
+65
cmake/sanitizers/FindTSan.cmake
···11+# The MIT License (MIT)
22+#
33+# Copyright (c)
44+# 2013 Matthew Arsenault
55+# 2015-2016 RWTH Aachen University, Federal Republic of Germany
66+#
77+# Permission is hereby granted, free of charge, to any person obtaining a copy
88+# of this software and associated documentation files (the "Software"), to deal
99+# in the Software without restriction, including without limitation the rights
1010+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1111+# copies of the Software, and to permit persons to whom the Software is
1212+# furnished to do so, subject to the following conditions:
1313+#
1414+# The above copyright notice and this permission notice shall be included in all
1515+# copies or substantial portions of the Software.
1616+#
1717+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1818+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1919+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2020+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2121+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2222+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2323+# SOFTWARE.
2424+2525+option(SANITIZE_THREAD "Enable ThreadSanitizer for sanitized targets." Off)
2626+2727+set(FLAG_CANDIDATES
2828+ "-g -fsanitize=thread"
2929+)
3030+3131+3232+# ThreadSanitizer is not compatible with MemorySanitizer.
3333+if (SANITIZE_THREAD AND SANITIZE_MEMORY)
3434+ message(FATAL_ERROR "ThreadSanitizer is not compatible with "
3535+ "MemorySanitizer.")
3636+endif ()
3737+3838+3939+include(sanitize-helpers)
4040+4141+if (SANITIZE_THREAD)
4242+ if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND
4343+ NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
4444+ message(WARNING "ThreadSanitizer disabled for target ${TARGET} because "
4545+ "ThreadSanitizer is supported for Linux systems and macOS only.")
4646+ set(SANITIZE_THREAD Off CACHE BOOL
4747+ "Enable ThreadSanitizer for sanitized targets." FORCE)
4848+ elseif (NOT ${CMAKE_SIZEOF_VOID_P} EQUAL 8)
4949+ message(WARNING "ThreadSanitizer disabled for target ${TARGET} because "
5050+ "ThreadSanitizer is supported for 64bit systems only.")
5151+ set(SANITIZE_THREAD Off CACHE BOOL
5252+ "Enable ThreadSanitizer for sanitized targets." FORCE)
5353+ else ()
5454+ sanitizer_check_compiler_flags("${FLAG_CANDIDATES}" "ThreadSanitizer"
5555+ "TSan")
5656+ endif ()
5757+endif ()
5858+5959+function (add_sanitize_thread TARGET)
6060+ if (NOT SANITIZE_THREAD)
6161+ return()
6262+ endif ()
6363+6464+ sanitizer_add_flags(${TARGET} "ThreadSanitizer" "TSan")
6565+endfunction ()
+46
cmake/sanitizers/FindUBSan.cmake
···11+# The MIT License (MIT)
22+#
33+# Copyright (c)
44+# 2013 Matthew Arsenault
55+# 2015-2016 RWTH Aachen University, Federal Republic of Germany
66+#
77+# Permission is hereby granted, free of charge, to any person obtaining a copy
88+# of this software and associated documentation files (the "Software"), to deal
99+# in the Software without restriction, including without limitation the rights
1010+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1111+# copies of the Software, and to permit persons to whom the Software is
1212+# furnished to do so, subject to the following conditions:
1313+#
1414+# The above copyright notice and this permission notice shall be included in all
1515+# copies or substantial portions of the Software.
1616+#
1717+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1818+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1919+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2020+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2121+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2222+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2323+# SOFTWARE.
2424+2525+option(SANITIZE_UNDEFINED
2626+ "Enable UndefinedBehaviorSanitizer for sanitized targets." Off)
2727+2828+set(FLAG_CANDIDATES
2929+ "-g -fsanitize=undefined"
3030+)
3131+3232+3333+include(sanitize-helpers)
3434+3535+if (SANITIZE_UNDEFINED)
3636+ sanitizer_check_compiler_flags("${FLAG_CANDIDATES}"
3737+ "UndefinedBehaviorSanitizer" "UBSan")
3838+endif ()
3939+4040+function (add_sanitize_undefined TARGET)
4141+ if (NOT SANITIZE_UNDEFINED)
4242+ return()
4343+ endif ()
4444+4545+ sanitizer_add_flags(${TARGET} "UndefinedBehaviorSanitizer" "UBSan")
4646+endfunction ()
+55
cmake/sanitizers/asan-wrapper
···11+#!/bin/sh
22+33+# The MIT License (MIT)
44+#
55+# Copyright (c)
66+# 2013 Matthew Arsenault
77+# 2015-2016 RWTH Aachen University, Federal Republic of Germany
88+#
99+# Permission is hereby granted, free of charge, to any person obtaining a copy
1010+# of this software and associated documentation files (the "Software"), to deal
1111+# in the Software without restriction, including without limitation the rights
1212+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1313+# copies of the Software, and to permit persons to whom the Software is
1414+# furnished to do so, subject to the following conditions:
1515+#
1616+# The above copyright notice and this permission notice shall be included in all
1717+# copies or substantial portions of the Software.
1818+#
1919+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2020+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2121+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2222+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2323+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2424+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2525+# SOFTWARE.
2626+2727+# This script is a wrapper for AddressSanitizer. In some special cases you need
2828+# to preload AddressSanitizer to avoid error messages - e.g. if you're
2929+# preloading another library to your application. At the moment this script will
3030+# only do something, if we're running on a Linux platform. OSX might not be
3131+# affected.
3232+3333+3434+# Exit immediately, if platform is not Linux.
3535+if [ "$(uname)" != "Linux" ]
3636+then
3737+ exec $@
3838+fi
3939+4040+4141+# Get the used libasan of the application ($1). If a libasan was found, it will
4242+# be prepended to LD_PRELOAD.
4343+libasan=$(ldd $1 | grep libasan | sed "s/^[[:space:]]//" | cut -d' ' -f1)
4444+if [ -n "$libasan" ]
4545+then
4646+ if [ -n "$LD_PRELOAD" ]
4747+ then
4848+ export LD_PRELOAD="$libasan:$LD_PRELOAD"
4949+ else
5050+ export LD_PRELOAD="$libasan"
5151+ fi
5252+fi
5353+5454+# Execute the application.
5555+exec $@
+177
cmake/sanitizers/sanitize-helpers.cmake
···11+# The MIT License (MIT)
22+#
33+# Copyright (c)
44+# 2013 Matthew Arsenault
55+# 2015-2016 RWTH Aachen University, Federal Republic of Germany
66+#
77+# Permission is hereby granted, free of charge, to any person obtaining a copy
88+# of this software and associated documentation files (the "Software"), to deal
99+# in the Software without restriction, including without limitation the rights
1010+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1111+# copies of the Software, and to permit persons to whom the Software is
1212+# furnished to do so, subject to the following conditions:
1313+#
1414+# The above copyright notice and this permission notice shall be included in all
1515+# copies or substantial portions of the Software.
1616+#
1717+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1818+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1919+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2020+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2121+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2222+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2323+# SOFTWARE.
2424+2525+# Helper function to get the language of a source file.
2626+function (sanitizer_lang_of_source FILE RETURN_VAR)
2727+ get_filename_component(LONGEST_EXT "${FILE}" EXT)
2828+ # If extension is empty return. This can happen for extensionless headers
2929+ if("${LONGEST_EXT}" STREQUAL "")
3030+ set(${RETURN_VAR} "" PARENT_SCOPE)
3131+ return()
3232+ endif()
3333+ # Get shortest extension as some files can have dot in their names
3434+ string(REGEX REPLACE "^.*(\\.[^.]+)$" "\\1" FILE_EXT ${LONGEST_EXT})
3535+ string(TOLOWER "${FILE_EXT}" FILE_EXT)
3636+ string(SUBSTRING "${FILE_EXT}" 1 -1 FILE_EXT)
3737+3838+ get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
3939+ foreach (LANG ${ENABLED_LANGUAGES})
4040+ list(FIND CMAKE_${LANG}_SOURCE_FILE_EXTENSIONS "${FILE_EXT}" TEMP)
4141+ if (NOT ${TEMP} EQUAL -1)
4242+ set(${RETURN_VAR} "${LANG}" PARENT_SCOPE)
4343+ return()
4444+ endif ()
4545+ endforeach()
4646+4747+ set(${RETURN_VAR} "" PARENT_SCOPE)
4848+endfunction ()
4949+5050+5151+# Helper function to get compilers used by a target.
5252+function (sanitizer_target_compilers TARGET RETURN_VAR)
5353+ # Check if all sources for target use the same compiler. If a target uses
5454+ # e.g. C and Fortran mixed and uses different compilers (e.g. clang and
5555+ # gfortran) this can trigger huge problems, because different compilers may
5656+ # use different implementations for sanitizers.
5757+ set(BUFFER "")
5858+ get_target_property(TSOURCES ${TARGET} SOURCES)
5959+ foreach (FILE ${TSOURCES})
6060+ # If expression was found, FILE is a generator-expression for an object
6161+ # library. Object libraries will be ignored.
6262+ string(REGEX MATCH "TARGET_OBJECTS:([^ >]+)" _file ${FILE})
6363+ if ("${_file}" STREQUAL "")
6464+ sanitizer_lang_of_source(${FILE} LANG)
6565+ if (LANG)
6666+ list(APPEND BUFFER ${CMAKE_${LANG}_COMPILER_ID})
6767+ endif ()
6868+ endif ()
6969+ endforeach ()
7070+7171+ list(REMOVE_DUPLICATES BUFFER)
7272+ set(${RETURN_VAR} "${BUFFER}" PARENT_SCOPE)
7373+endfunction ()
7474+7575+7676+# Helper function to check compiler flags for language compiler.
7777+function (sanitizer_check_compiler_flag FLAG LANG VARIABLE)
7878+ if (${LANG} STREQUAL "C")
7979+ include(CheckCCompilerFlag)
8080+ check_c_compiler_flag("${FLAG}" ${VARIABLE})
8181+8282+ elseif (${LANG} STREQUAL "CXX")
8383+ include(CheckCXXCompilerFlag)
8484+ check_cxx_compiler_flag("${FLAG}" ${VARIABLE})
8585+8686+ elseif (${LANG} STREQUAL "Fortran")
8787+ # CheckFortranCompilerFlag was introduced in CMake 3.x. To be compatible
8888+ # with older Cmake versions, we will check if this module is present
8989+ # before we use it. Otherwise we will define Fortran coverage support as
9090+ # not available.
9191+ include(CheckFortranCompilerFlag OPTIONAL RESULT_VARIABLE INCLUDED)
9292+ if (INCLUDED)
9393+ check_fortran_compiler_flag("${FLAG}" ${VARIABLE})
9494+ elseif (NOT CMAKE_REQUIRED_QUIET)
9595+ message(STATUS "Performing Test ${VARIABLE}")
9696+ message(STATUS "Performing Test ${VARIABLE}"
9797+ " - Failed (Check not supported)")
9898+ endif ()
9999+ endif()
100100+endfunction ()
101101+102102+103103+# Helper function to test compiler flags.
104104+function (sanitizer_check_compiler_flags FLAG_CANDIDATES NAME PREFIX)
105105+ set(CMAKE_REQUIRED_QUIET ${${PREFIX}_FIND_QUIETLY})
106106+107107+ get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
108108+ foreach (LANG ${ENABLED_LANGUAGES})
109109+ # Sanitizer flags are not dependend on language, but the used compiler.
110110+ # So instead of searching flags foreach language, search flags foreach
111111+ # compiler used.
112112+ set(COMPILER ${CMAKE_${LANG}_COMPILER_ID})
113113+ if (NOT DEFINED ${PREFIX}_${COMPILER}_FLAGS)
114114+ foreach (FLAG ${FLAG_CANDIDATES})
115115+ if(NOT CMAKE_REQUIRED_QUIET)
116116+ message(STATUS "Try ${COMPILER} ${NAME} flag = [${FLAG}]")
117117+ endif()
118118+119119+ set(CMAKE_REQUIRED_FLAGS "${FLAG}")
120120+ unset(${PREFIX}_FLAG_DETECTED CACHE)
121121+ sanitizer_check_compiler_flag("${FLAG}" ${LANG}
122122+ ${PREFIX}_FLAG_DETECTED)
123123+124124+ if (${PREFIX}_FLAG_DETECTED)
125125+ # If compiler is a GNU compiler, search for static flag, if
126126+ # SANITIZE_LINK_STATIC is enabled.
127127+ if (SANITIZE_LINK_STATIC AND (${COMPILER} STREQUAL "GNU"))
128128+ string(TOLOWER ${PREFIX} PREFIX_lower)
129129+ sanitizer_check_compiler_flag(
130130+ "-static-lib${PREFIX_lower}" ${LANG}
131131+ ${PREFIX}_STATIC_FLAG_DETECTED)
132132+133133+ if (${PREFIX}_STATIC_FLAG_DETECTED)
134134+ set(FLAG "-static-lib${PREFIX_lower} ${FLAG}")
135135+ endif ()
136136+ endif ()
137137+138138+ set(${PREFIX}_${COMPILER}_FLAGS "${FLAG}" CACHE STRING
139139+ "${NAME} flags for ${COMPILER} compiler.")
140140+ mark_as_advanced(${PREFIX}_${COMPILER}_FLAGS)
141141+ break()
142142+ endif ()
143143+ endforeach ()
144144+145145+ if (NOT ${PREFIX}_FLAG_DETECTED)
146146+ set(${PREFIX}_${COMPILER}_FLAGS "" CACHE STRING
147147+ "${NAME} flags for ${COMPILER} compiler.")
148148+ mark_as_advanced(${PREFIX}_${COMPILER}_FLAGS)
149149+150150+ message(WARNING "${NAME} is not available for ${COMPILER} "
151151+ "compiler. Targets using this compiler will be "
152152+ "compiled without ${NAME}.")
153153+ endif ()
154154+ endif ()
155155+ endforeach ()
156156+endfunction ()
157157+158158+159159+# Helper to assign sanitizer flags for TARGET.
160160+function (sanitizer_add_flags TARGET NAME PREFIX)
161161+ # Get list of compilers used by target and check, if sanitizer is available
162162+ # for this target. Other compiler checks like check for conflicting
163163+ # compilers will be done in add_sanitizers function.
164164+ sanitizer_target_compilers(${TARGET} TARGET_COMPILER)
165165+ list(LENGTH TARGET_COMPILER NUM_COMPILERS)
166166+ if ("${${PREFIX}_${TARGET_COMPILER}_FLAGS}" STREQUAL "")
167167+ return()
168168+ endif()
169169+170170+ # Set compile- and link-flags for target.
171171+ set_property(TARGET ${TARGET} APPEND_STRING
172172+ PROPERTY COMPILE_FLAGS " ${${PREFIX}_${TARGET_COMPILER}_FLAGS}")
173173+ set_property(TARGET ${TARGET} APPEND_STRING
174174+ PROPERTY COMPILE_FLAGS " ${SanBlist_${TARGET_COMPILER}_FLAGS}")
175175+ set_property(TARGET ${TARGET} APPEND_STRING
176176+ PROPERTY LINK_FLAGS " ${${PREFIX}_${TARGET_COMPILER}_FLAGS}")
177177+endfunction ()