From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <v.shpilevoy@tarantool.org>
Received: from smtp58.i.mail.ru (smtp58.i.mail.ru [217.69.128.38])
 (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
 (No client certificate requested)
 by dev.tarantool.org (Postfix) with ESMTPS id 492B64696C2
 for <tarantool-patches@dev.tarantool.org>;
 Thu, 21 May 2020 23:37:39 +0300 (MSK)
From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org>
Date: Thu, 21 May 2020 22:37:26 +0200
Message-Id: <2e24204c8064d0c81e1baf81e9e23247199d083f.1590093222.git.v.shpilevoy@tarantool.org>
In-Reply-To: <cover.1590093222.git.v.shpilevoy@tarantool.org>
References: <cover.1590093222.git.v.shpilevoy@tarantool.org>
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
Subject: [Tarantool-patches] [PATCH 03/10] cmake: add option
	ENABLE_UB_SANITIZER
List-Id: Tarantool development patches <tarantool-patches.dev.tarantool.org>
List-Unsubscribe: <https://lists.tarantool.org/mailman/options/tarantool-patches>, 
 <mailto:tarantool-patches-request@dev.tarantool.org?subject=unsubscribe>
List-Archive: <https://lists.tarantool.org/pipermail/tarantool-patches/>
List-Post: <mailto:tarantool-patches@dev.tarantool.org>
List-Help: <mailto:tarantool-patches-request@dev.tarantool.org?subject=help>
List-Subscribe: <https://lists.tarantool.org/mailman/listinfo/tarantool-patches>, 
 <mailto:tarantool-patches-request@dev.tarantool.org?subject=subscribe>
To: tarantool-patches@dev.tarantool.org, korablev@tarantool.org, tsafin@tarantool.org, alyapunov@tarantool.org, gorcunov@gmail.com

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.

Sometimes it happens that unaligned memory access is done
intentionally, or can't be simply fixed. To disable the sanitizer
for such places an attribute 'no_sanitize' can be used. It is
added inside a macro NOSANITIZE_ALIGN.

Part of #4609
---
 cmake/compiler.cmake | 10 ++++++++++
 src/trivia/util.h    |  6 ++++++
 2 files changed, 16 insertions(+)

diff --git a/cmake/compiler.cmake b/cmake/compiler.cmake
index ce3e7e506..373bcd3b0 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")
diff --git a/src/trivia/util.h b/src/trivia/util.h
index 8a3d22b38..466cb6e55 100644
--- a/src/trivia/util.h
+++ b/src/trivia/util.h
@@ -392,6 +392,12 @@ strnindex(const char **haystack, const char *needle, uint32_t len, uint32_t hmax
 
 /** \endcond public */
 
+#if __has_attribute(no_sanitize)
+#define NOSANITIZE_ALIGN __attribute__((no_sanitize("alignment")))
+#else
+#define NOSANITIZE_ALIGN
+#endif
+
 void close_all_xcpt(int fdc, ...);
 
 void __gcov_flush();
-- 
2.21.1 (Apple Git-122.3)