diff --git a/CMakeLists.txt b/CMakeLists.txt index 1fe5642..f76f636 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,6 +62,7 @@ add_definitions(${LLVM_DEFINITIONS}) set(LLVM_LIT_ARGS "-sv" CACHE STRING "lit default options") list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/modules") +include(sanitizers) add_subdirectory(include) add_subdirectory(mlir-clang) diff --git a/cmake/modules/sanitizers.cmake b/cmake/modules/sanitizers.cmake new file mode 100644 index 0000000..675f114 --- /dev/null +++ b/cmake/modules/sanitizers.cmake @@ -0,0 +1,148 @@ +# +# Original source: Copyright (C) 2018 by George Cave - gcave@stablecoder.ca +# Modified source: Copyright (C) 2020 by Jean-Michel Gorius +# - jean-michel.gorius@ens-rennes.fr +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# Adapted by Jean-Michel Gorius to forward sanitizer flags to the linker. +# + +set(USE_SANITIZER + "" + CACHE + STRING + "Compile with a sanitizer. Options are: Address, Memory, MemoryWithOrigins, Undefined, Thread, Leak, 'Address;Undefined'" + ) + +function(append value) + foreach (variable ${ARGN}) + set(${variable} + "${${variable}} ${value}" + PARENT_SCOPE) + endforeach (variable) +endfunction() + +if (USE_SANITIZER) + append("-fno-omit-frame-pointer" + CMAKE_C_FLAGS + CMAKE_CXX_FLAGS) + + if (UNIX) + + if (uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG") + append("-O1" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) + endif () + + if (USE_SANITIZER MATCHES "([Aa]ddress);([Uu]ndefined)" + OR USE_SANITIZER MATCHES "([Uu]ndefined);([Aa]ddress)") + message(STATUS "Building with Address, Undefined sanitizers") + append("-fsanitize=address,undefined" + CMAKE_EXE_C_FLAGS + CMAKE_EXE_CXX_FLAGS + CMAKE_STATIC_C_FLAGS + CMAKE_STATIC_CXX_FLAGS + CMAKE_EXE_LINKER_FLAGS + CMAKE_MODULE_LINKER_FLAGS) + elseif (USE_SANITIZER MATCHES "([Aa]ddress)") + # Optional: -fno-optimize-sibling-calls -fsanitize-address-use-after-scope + message(STATUS "Building with Address sanitizer") + append("-fsanitize=address" + CMAKE_EXE_C_FLAGS + CMAKE_EXE_CXX_FLAGS + CMAKE_STATIC_C_FLAGS + CMAKE_STATIC_CXX_FLAGS + CMAKE_EXE_LINKER_FLAGS + CMAKE_MODULE_LINKER_FLAGS) + elseif (USE_SANITIZER MATCHES "([Mm]emory([Ww]ith[Oo]rigins)?)") + # Optional: -fno-optimize-sibling-calls -fsanitize-memory-track-origins=2 + append("-fsanitize=memory" + CMAKE_EXE_C_FLAGS + CMAKE_EXE_CXX_FLAGS + CMAKE_STATIC_C_FLAGS + CMAKE_STATIC_CXX_FLAGS + CMAKE_EXE_LINKER_FLAGS + CMAKE_MODULE_LINKER_FLAGS) + if (USE_SANITIZER MATCHES "([Mm]emory[Ww]ith[Oo]rigins)") + message(STATUS "Building with MemoryWithOrigins sanitizer") + append("-fsanitize-memory-track-origins" + CMAKE_EXE_C_FLAGS + CMAKE_EXE_CXX_FLAGS + CMAKE_STATIC_C_FLAGS + CMAKE_STATIC_CXX_FLAGS + CMAKE_EXE_LINKER_FLAGS + CMAKE_MODULE_LINKER_FLAGS) + else () + message(STATUS "Building with Memory sanitizer") + endif () + elseif (USE_SANITIZER MATCHES "([Uu]ndefined)") + message(STATUS "Building with Undefined sanitizer") + append("-fsanitize=undefined" + CMAKE_EXE_C_FLAGS + CMAKE_EXE_CXX_FLAGS + CMAKE_STATIC_C_FLAGS + CMAKE_STATIC_CXX_FLAGS + CMAKE_EXE_LINKER_FLAGS + CMAKE_MODULE_LINKER_FLAGS) + if (EXISTS "${BLACKLIST_FILE}") + append("-fsanitize-blacklist=${BLACKLIST_FILE}" + CMAKE_EXE_C_FLAGS + CMAKE_EXE_CXX_FLAGS + CMAKE_STATIC_C_FLAGS + CMAKE_STATIC_CXX_FLAGS + CMAKE_EXE_LINKER_FLAGS + CMAKE_MODULE_LINKER_FLAGS) + endif () + elseif (USE_SANITIZER MATCHES "([Tt]hread)") + message(STATUS "Building with Thread sanitizer") + append("-fsanitize=thread" + CMAKE_EXE_C_FLAGS + CMAKE_EXE_CXX_FLAGS + CMAKE_STATIC_C_FLAGS + CMAKE_STATIC_CXX_FLAGS + CMAKE_EXE_LINKER_FLAGS + CMAKE_MODULE_LINKER_FLAGS) + elseif (USE_SANITIZER MATCHES "([Ll]eak)") + message(STATUS "Building with Leak sanitizer") + append("-fsanitize=leak" + CMAKE_EXE_C_FLAGS + CMAKE_EXE_CXX_FLAGS + CMAKE_STATIC_C_FLAGS + CMAKE_STATIC_CXX_FLAGS + CMAKE_EXE_LINKER_FLAGS + CMAKE_MODULE_LINKER_FLAGS) + else () + message( + FATAL_ERROR "Unsupported value of USE_SANITIZER: ${USE_SANITIZER}") + endif () + elseif (MSVC) + if (USE_SANITIZER MATCHES "([Aa]ddress)") + message(STATUS "Building with Address sanitizer") + append("-fsanitize=address" + CMAKE_EXE_C_FLAGS + CMAKE_EXE_CXX_FLAGS + CMAKE_STATIC_C_FLAGS + CMAKE_STATIC_CXX_FLAGS + CMAKE_EXE_LINKER_FLAGS + CMAKE_MODULE_LINKER_FLAGS) + else () + message( + FATAL_ERROR + "This sanitizer is not yet supported in the MSVC environment: ${USE_SANITIZER}" + ) + endif () + else () + message(FATAL_ERROR "USE_SANITIZER is not supported on this platform.") + endif () + +endif ()