From 8b7f6f5a5b17117e9da8c1497937da80ea72e5b9 Mon Sep 17 00:00:00 2001
From: Lucian Grijincu <lucian@fb.com>
Date: Mon, 1 Feb 2016 17:00:24 -0800
Subject: [PATCH] folly: #define UNDEFINED_SANITIZER in ubsan mode

Summary:
Undefined Sanitizer doesn't define any macro to detect that it's active.

The build system should provide `-DUNDEFINED_SANITIZER` when building
with -fsanitize=undefined or any of the other flags from
http://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html

FWIW: Chrome defines the same preprocessor symbol:
https://chromium.googlesource.com/chromium/src/+/ac18f489dca8c902e4dfaa1a28d716b7914121d0%5E%21/build/common.gypi

Reviewed By: andrewjcg

Differential Revision: D2885167

fb-gh-sync-id: e1129c0863bfde5d032c32e7d5cea7c43d82009f
---
 folly/CPortability.h      | 19 ++++++++++++++++++-
 folly/test/MemcpyTest.cpp |  4 +++-
 2 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/folly/CPortability.h b/folly/CPortability.h
index e5099d23..c348b361 100644
--- a/folly/CPortability.h
+++ b/folly/CPortability.h
@@ -56,4 +56,21 @@
 # define FOLLY_DISABLE_ADDRESS_SANITIZER
 #endif
 
-#endif
+
+/**
+ * ASAN/MSAN/TSAN define pre-processor symbols:
+ * ADDRESS_SANITIZER/MEMORY_SANITIZER/THREAD_SANITIZER.
+ *
+ * UBSAN doesn't define anything and makes it hard to
+ * conditionally compile.
+ *
+ * The build system should define UNDEFINED_SANITIZER=1 when UBSAN is
+ * used as folly whitelists some functions.
+ */
+#if UNDEFINED_SANITIZER
+# define UBSAN_DISABLE(x) __attribute__((no_sanitize(x)))
+#else
+# define UBSAN_DISABLE(x)
+#endif // UNDEFINED_SANITIZER
+
+#endif // CPORTABILITY_H
diff --git a/folly/test/MemcpyTest.cpp b/folly/test/MemcpyTest.cpp
index badd3447..73b64ca1 100644
--- a/folly/test/MemcpyTest.cpp
+++ b/folly/test/MemcpyTest.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include <folly/Portability.h>
+
 #include <gtest/gtest.h>
 
 namespace {
@@ -30,7 +32,7 @@ void init() {
 }
 }
 
-TEST(memcpy, zero_len) {
+TEST(memcpy, zero_len) UBSAN_DISABLE("nonnull-attribute") {
   // If length is 0, we shouldn't touch any memory.  So this should
   // not crash.
   char* srcNull = nullptr;
-- 
2.34.1