From 366cb668fb5c596fba522003a2e45aefdcd0d599 Mon Sep 17 00:00:00 2001
From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org>
Date: Thu, 21 May 2020 21:45:07 +0200
Subject: [PATCH] cmake: add option ENABLE_UB_SANITIZER

Clang has a built-in sanitizer for undefined behaviour. Such as
wrong memory alignment, array boundaries violation, 0 division,
bool values with non standard content, etc.

The sanitizer emits runtime checks which lead to either crash, or
a trap, or a warning print, depending on what is chosen.

The patch makes it possible to turn the sanitizer on and catch
UBs. The only supported UB so far is alignment check. Other types
can be added gradually, along with fixing bugs which they find.

The UB sanitizer is activated for ASAN builds in CI.

Part of #4609
---
 .travis.mk           |  3 ++-
 CMakeLists.txt       |  2 +-
 cmake/compiler.cmake | 10 ++++++++++
 3 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/.travis.mk b/.travis.mk
index 063537f257..748321f262 100644
--- a/.travis.mk
+++ b/.travis.mk
@@ -114,7 +114,8 @@ coverage_debian: deps_debian test_coverage_debian_no_deps
 
 build_asan_debian:
 	CC=clang-8 CXX=clang++-8 cmake . -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-		-DENABLE_WERROR=ON -DENABLE_ASAN=ON ${CMAKE_EXTRA_PARAMS}
+		-DENABLE_WERROR=ON -DENABLE_ASAN=ON -DENABLE_UB_SANITIZER=ON \
+		${CMAKE_EXTRA_PARAMS}
 	make -j
 
 test_asan_debian_no_deps: build_asan_debian
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1d80b6806a..e49317f8a1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -571,7 +571,7 @@ set(PREFIX ${CMAKE_INSTALL_PREFIX})
 set(options PACKAGE VERSION BUILD C_COMPILER CXX_COMPILER C_FLAGS CXX_FLAGS
     PREFIX
     ENABLE_SSE2 ENABLE_AVX
-    ENABLE_GCOV ENABLE_GPROF ENABLE_VALGRIND ENABLE_ASAN
+    ENABLE_GCOV ENABLE_GPROF ENABLE_VALGRIND ENABLE_ASAN ENABLE_UB_SANITIZER
     ENABLE_BACKTRACE
     ENABLE_DOC
     ENABLE_DIST
diff --git a/cmake/compiler.cmake b/cmake/compiler.cmake
index b0908f3b3c..4b23d6631b 100644
--- a/cmake/compiler.cmake
+++ b/cmake/compiler.cmake
@@ -238,6 +238,8 @@ endif()
 
 option(ENABLE_WERROR "Make all compiler warnings into errors" OFF)
 
+option(ENABLE_UB_SANITIZER "Make the compiler generate runtime code to perform undefined behaviour checks" OFF)
+
 macro(enable_tnt_compile_flags)
     # Tarantool code is written in GNU C dialect.
     # Additionally, compile it with more strict flags than the rest
@@ -263,6 +265,14 @@ macro(enable_tnt_compile_flags)
         "-Wno-strict-aliasing"
     )
 
+    if (ENABLE_UB_SANITIZER)
+        if (NOT CMAKE_COMPILER_IS_CLANG)
+            message(FATAL_ERROR "Undefined behaviour sanitizer only available for clang")
+        else()
+            add_compile_flags("C;CXX" "-fsanitize=alignment -fno-sanitize-recover=alignment")
+        endif()
+    endif()
+
     if (CMAKE_COMPILER_IS_CLANG AND CC_HAS_WNO_UNUSED_VALUE)
         # False-positive warnings for ({ xx = ...; x; }) macroses
         add_compile_flags("C;CXX" "-Wno-unused-value")
-- 
GitLab