From d36dcacc44a1cd45275ed86a6110abd7c07a11b1 Mon Sep 17 00:00:00 2001 From: Jean-Michel Gorius Date: Thu, 11 Jun 2020 11:02:43 +0200 Subject: [PATCH] Add support for sanitizer builds This could be helpful to solve issues like #22. --- CMakeLists.txt | 7 +-- cmake/modules/sanitizers.cmake | 88 ++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 cmake/modules/sanitizers.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index d8861e0..116c440 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,5 @@ cmake_minimum_required(VERSION 3.10) - - project(oec-opt LANGUAGES CXX C) include(CheckLanguage) @@ -40,7 +38,10 @@ include_directories(${PROJECT_BINARY_DIR}/include) link_directories(${LLVM_BUILD_LIBRARY_DIR}) add_definitions(${LLVM_DEFINITIONS}) +list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/modules") +include(sanitizers) + add_subdirectory(include) add_subdirectory(lib) add_subdirectory(test) -add_subdirectory(oec-opt) \ No newline at end of file +add_subdirectory(oec-opt) diff --git a/cmake/modules/sanitizers.cmake b/cmake/modules/sanitizers.cmake new file mode 100644 index 0000000..2f5d217 --- /dev/null +++ b/cmake/modules/sanitizers.cmake @@ -0,0 +1,88 @@ +# +# Copyright (C) 2018 by George Cave - gcave@stablecoder.ca +# +# 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. + +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_C_FLAGS CMAKE_CXX_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_C_FLAGS CMAKE_CXX_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_C_FLAGS CMAKE_CXX_FLAGS) + if (USE_SANITIZER MATCHES "([Mm]emory[Ww]ith[Oo]rigins)") + message(STATUS "Building with MemoryWithOrigins sanitizer") + append("-fsanitize-memory-track-origins" CMAKE_C_FLAGS CMAKE_CXX_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_C_FLAGS CMAKE_CXX_FLAGS) + if (EXISTS "${BLACKLIST_FILE}") + append("-fsanitize-blacklist=${BLACKLIST_FILE}" CMAKE_C_FLAGS + CMAKE_CXX_FLAGS) + endif () + elseif (USE_SANITIZER MATCHES "([Tt]hread)") + message(STATUS "Building with Thread sanitizer") + append("-fsanitize=thread" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) + elseif (USE_SANITIZER MATCHES "([Ll]eak)") + message(STATUS "Building with Leak sanitizer") + append("-fsanitize=leak" CMAKE_C_FLAGS CMAKE_CXX_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_C_FLAGS CMAKE_CXX_FLAGS) + else () + message( + FATAL_ERROR + "This sanitizer not yet supported in the MSVC environment: ${USE_SANITIZER}" + ) + endif () + else () + message(FATAL_ERROR "USE_SANITIZER is not supported on this platform.") + endif () + +endif () \ No newline at end of file